0

I am trying to move a stepper motor when a specific command is send to Arduino Mega 2560. This command is read character by character and stored in a string variable. Whenever a new command is sent, an act should be performed. However, it is not happening and I believe that the problem is in reading the sent command. I tried clearing the character and string variables, but to no avail. The sketch should run a loop that moves the motor clockwise or counterclockwise according to the command sent, which can be "crx*" for clockwise or "clx*" for anticlockwise, where "*" is the reading stop criterion of the characters. Any suggestions what to do? The script:

void(* resetFunc) (void) = 0;//Reset turn

// Stepper Motor X const int stepPinX = 2; //X.STEP const int dirPinX = 5; // X.DIR const int pinEnable = 8;

// String read char c; String readString; //main captured String

// Unit steps double av_len = 1.029; //medium length double interval; int cnt_steps = 0; const int num_d = 200;//parameterized step int fact = int(num_d / av_len); int unit_len = fact * 1;//unit length (1mm)

void setup() { // Sets pins as Outputs pinMode(stepPinX, OUTPUT); pinMode(dirPinX, OUTPUT); pinMode(pinEnable, OUTPUT);

digitalWrite(pinEnable, HIGH);//lock driver on cnc shield

Serial.begin(115200); Serial.setTimeout(1);

while (1) {

while ( (Serial.available() == 0) )
{

}

if (Serial.available())  {
  c = Serial.read();  //gets one byte from serial buffer
  //Serial.println(readString);
  if (c == '*') {
    Serial.println(readString);//test response
    if (readString == "crx") {
      cnt_steps = cnt_steps + 1;
      Serial.println(cnt_steps);
      digitalWrite(pinEnable, LOW);
      digitalWrite(dirPinX, HIGH);
      for (int x = 0; x < unit_len; x++) {
        digitalWrite(stepPinX, HIGH);
        delayMicroseconds(500);
        digitalWrite(stepPinX, LOW);
        delayMicroseconds(500);
      }

    }
    else if (readString == "clx") {
      cnt_steps += -1;
      Serial.println(cnt_steps);
      digitalWrite(pinEnable, LOW);
      digitalWrite(dirPinX, LOW);
      for (int x = 0; x < unit_len; x++) {
        digitalWrite(stepPinX, HIGH);
        delayMicroseconds(500);
        digitalWrite(stepPinX, LOW);
        delayMicroseconds(500);
      }
    }
     digitalWrite(pinEnable, HIGH);//lock driver on cnc shield    
     c = (char)0;
     Serial.flush();
     readString = "";
     //resetFunc();
  }

  else {
    readString += c; //makes the string readString

  }
}

} }

void loop() {

}

2 Answers2

1

When sending text commands to an Arduino, it is common to define a “line-oriented protocol”: each command is transmitted as a single line, with the line ending signifying the end of the command. Common line endings are carriage return (CR = '\r' = 0x0d = 13), line feed (LF = '\n' = 0x0a = 10) and the sequence CR+LF.

The Arduino serial monitor is designed to support this convention by automatically appending a line ending when you press “Send”. This line ending can be configured to one of the following options:

  • No line ending
  • Newline (meaning “line feed”)
  • Carriage return
  • Both NL & CR (but CR is actually sent before LF)

In your case, you have chosen to use '*' as a command termination character. For this to work, you have to choose “No line ending” and add the “*” explicitly to the command. Alternatively, you may consider changing your sketch so that it expects '\r' or '\n', which is a more standard way of ending a command.

Edgar Bonet
  • 45,094
  • 4
  • 42
  • 81
0

In addition to the good responses you have already received, I offer this.

For the Arduino, know the differences between String string and char arrays - there is much on this e.g., https://forum.arduino.cc/t/string-vs-string-vs-char-arrays-correct-approach/537468 . Many do not want to deal with the vagaries of String, but their use can be convenient.

Run this code:

String readstring = "xxx";

void setup() { Serial.begin(115200); }

void loop() { if (Serial.available()) { readstring = Serial.readStringUntil('/n'); Serial.print(readstring); Serial.println(" received"); if (readstring.equals("crx")) { // move counter clockwise Serial.println("moving counter clockwise"); // counterclockwise() <-- your function } else if (readstring.equals("clx") ) { // move clockwise Serial.println("moving clockwise"); // clockwise() <-- your function } else { // bad command Serial.println("Bad command received - no action"); // badcommand() <-- your function } } }

If you add functions for the stepper, it may do what you want within a limited context and with using the Arduino serial monitor for input. Take a look at the output.

enter image description here

Note that the serial monitor is set to "no line ending". The terminating character '/n' is provide by your input in the serial monitor. It will do what you want, but again, many advise you stay away from String.

DrG
  • 409
  • 3
  • 7