Receiving Serial port commands inside loop() not working correctly

Hello!

My project is making an Alt/Az telescope mount which receives commands from a WinForm C# app. The commands are ok, motors rotate ok. Now I want to implement Manual Control, namely, make the motors microstep X steps to better position the telescope and make also a sort of semi-auto tracking with this.

In my mind the below code should do the following:

  1. enter "AMOV";
  2. read direction;
  3. according to the direction, move motor X microsteps;
  4. basically at every click, let's say "NORT" in the WinForm app, the AZ_stepper should move X microsteps upwards;
  5. exit the "AMOV" only if "DMOV" is received inside;

So the code, in loop(), according to the received command, is executed. When I send "AMOV", it goes as far as receiving the direction, starts moving the motor but another direction is not received and the motor is spinning forever. Thus, the Arduino and the motor can be stopped only by unplugging it from the power supply.
Worth mentioning is that I already have a function serialEvent that listens for commands like "AMOV", "SLEW", "HOME", "PARK", OUTSIDE the loop() function. I try to implement another kind of serial listening inside loop(), inside a received command. Thus, I am wondering if it is possible. If not, other suggestions would be welcomed! If yes, help on this situation would be great!

Here is the loop() code:

else if(commandString.equals("AMOV"))
    {
      ManualMovement = true;
      double DegPerStep = 0.01125;
      double DegToMove;
      //DegToMove = 0.1;//DegPerStep * 5;
      int ms = 20;

      //Manual Control of the telescope
      while(ManualMovement == true)
      {
        turnLedOn(led2Pin); 

        if(Serial.available() && ReceivedDirection == false)
        {
          //char c = (char)Serial.read();
          direction = Serial.readString();

          //if(c == '\n')
          //{
            if(direction.length() > 0)
            ReceivedDirection = true;
          //}
        }

        if(ReceivedDirection == true)
        {
          
          getDirection();
          turnLedOff(led2Pin);

          AZ_stepper.setMicrostep(32);
          ALT_stepper.setMicrostep(32);

          if(movement.equals("NORT"))
          {
            for(int i=0; i<2; i++)
            {
            ALT_stepper.move(1);
            delay(5);
            turnLedOn(led2Pin);
            }
            turnLedOff(led2Pin);
          }
          else if(movement.equals("SOUT"))
          {
            ALT_stepper.move(-ms);
            delay(5);
            turnLedOff(led2Pin);
          }
          else if(movement.equals("EAST"))
          {
            AZ_stepper.move(-ms);
            delay(5);
          }
          else if(movement.equals("WEST"))
          {
            AZ_stepper.move(ms);
            delay(5);
          }
          else if(movement.equals("DMOV"))
          {
            ManualMovement = false;
            ReceivedDirection == false;
          }

          direction = "";
        }
      }
    }

And here the serialEvent code outside loop():

void serialEvent() 
{
  while (Serial.available()) 
  {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') 
    {
      stringComplete = true;
    }
  }
}

Thank you for reading and for helping!

What device do you have to display debugging information?

No device. A possibility is to use Serial.write() to display some information in the application.

what Arduino board are you using? SerialEvent does not work on all boards

SerialEvent documentation states it is called at the end of loop() execution, i.e. it is polling the serial input and not what one thinks of as an Event Handler which executes concurrently with other code

when testing are you using your C# program or typing commands into the Serial Monitor - in general I use the latter for initial testing

Please post complete code.

Only if movement is equal to DMOV, you will set ManualMovement to false; but it's nowhere to be found where movement is changed in the while-loop (as far as I can see) so you're stuck there.

// Edit
while-loops and for-loops basically have no place in Arduino code; exception is e.g. initialisation of arrays etc. You will have to learn to write non-blocking code.

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