Sending data over Serial communication has 1 second delay

Dear user of the forum,

I am currently doing a project where I am designing, and programming a scara robot completely from scratch. Currently I have the prototype design fabricated and ready to be used and I am now officially working on the software.

I managed to write software in C# (I wrote in C# due to experience gained during my education) which allows me to have a GUI and a G-code data converted. The way my software works is:

  • Reads G-code file
  • Manipulates data
  • Converts coordinates into stepper angles
  • Converts angles into steps
    When these steps are calculated they will be send in pairs of steps over the serial port in the following format: 100,50
    100 means stepper 1 should take 100 steps and 50 means stepper 2 should take 50 steps.
    When the stepper motor is done it will send the character x to the c# software which then knows the arduino is ready to recieve the new stepper position (See Arduino code below).

Now the problem that I have is that there seems to be a 1 second delay between the arduino sending the "x" character and the arduino recieving the new stepper positions from the C# software.

Do any of you know what I might be doing wrong in my code which causes this 1 second delay to occur? (Inverse kinematics calculations take place outside of the arduino on my laptop and only take about 0.004 seconds)

Arduino code:

#include <AccelStepper.h>

AccelStepper Motorjoint1(1, 2, 3); // pin 3 = step, pin 6 = direction
AccelStepper Motorjoint2(1, 8, 9); // pin 3 = step, pin 6 = direction

int movementdone = 0;

void setup() 
{
  Serial.begin(115200);
  Motorjoint1.setMaxSpeed(50000);
  Motorjoint1.setAcceleration(2000);
  Motorjoint1.setSpeed(200);
  //Motorjoint1.setCurrentPosition(300);
  Motorjoint2.setMaxSpeed(50000);
  Motorjoint2.setAcceleration(2000);
  Motorjoint2.setSpeed(200);
  //Motorjoint2.setCurrentPosition(-40);
}

void loop() 
{  
  if(Serial.available())
  {
    String holders = Serial.readString();
    int commaIndex = holders.indexOf(',');
    String joint1 = holders.substring(0, commaIndex);
    String joint2 = holders.substring(commaIndex +1, holders.length());

    int t1 = joint1.toInt();
    int t2 = joint2.toInt();
    
    Motorjoint1.moveTo((t1*4)*-1);
    Motorjoint2.moveTo((t2)*4); 

    while(abs(Motorjoint1.distanceToGo()) !=0 || abs(Motorjoint2.distanceToGo()) !=0 )
    {
      Motorjoint1.run();
      Motorjoint2.run();
    }
   
    if((Motorjoint1.distanceToGo() == 0) && (Motorjoint2.distanceToGo() == 0) && (movementdone == 0))
    { 
      movementdone++;     
      Serial.println("x");
    }
  }
}

C# communication code with arduino:

        private async void button1_Click(object sender, EventArgs e)
        {
            port = new SerialPort();
            port.PortName = "COM7";
            port.BaudRate = 115200;

            try
            {
                port.Open();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            if (port.IsOpen)
            {
                for(int i = 0; i < dataGridView1.RowCount - 1; i++)
                {
                    if(dataGridView1.Rows[i].Cells[2].Value.ToString().Contains(','))
                    {
                        DateTime t1 = DateTime.Now;
                        InverseKinematics InvKin_1 = new InverseKinematics(Convert.ToDouble(dataGridView1.Rows[i].Cells[2].Value), Convert.ToDouble(dataGridView1.Rows[i].Cells[3].Value));
                        string steps_to_take = Convert.ToString(Math.Ceiling(InvKin_1.Inverse_V2_Theta1()/0.45)) + ',' + Convert.ToString(Math.Ceiling(InvKin_1.Inverse_V2_Theta2()/0.45));
                        
                        System.Console.WriteLine(steps_to_take);
                        port.WriteLine(steps_to_take);
                        DateTime t2 = DateTime.Now;
                        TimeSpan t3 = t2 - t1;
                        System.Console.WriteLine(t3);
                        port.ReadLine().ToString().Contains("x");
                        
                    }
                }
                port.Close();
                MessageBox.Show("G-code finished");
            }
        }

Hopefully my explantation is clear and some of you might know what I am doing wrong.

Thank you in advance

-C

Try changing the timeout, or use a more responsive technique.

1 Like

The serial input basics tutorial shows robust ways to read and parse serial data without using the potentially problematic String class.

consider using readBytesUntil() recognizing the line terminator (\n or \r)

Thank you so much,

This is indeed the answer I was looking for. I didn't look into the Serial() data sheet. Turns out the default Serial.Timeout() is set to 1000 milliseconds. A quick change to 2 milli seconds (baudrate/max. amount of bits sent) solved the problem.

A simple change in the setup code showed how easy this solution actually was haha:

void setup() 
{
  Serial.setTimeout(2); //Milliseconds
  Serial.begin(115200);
  Motorjoint1.setMaxSpeed(50000);
  Motorjoint1.setAcceleration(2000);
  Motorjoint1.setSpeed(200);
  Motorjoint2.setMaxSpeed(50000);
  Motorjoint2.setAcceleration(2000);
  Motorjoint2.setSpeed(200);
}
1 Like

It's a sticking plaster rather than a solution; much better to use more robust methods, like looking for line endings, as mentioned.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.