Search code examples
arduinog-code

Arduino Gcode reader


I made G-code reader on Arduino, but it stops reading. It has many "break;" and I have also many while loops and switches, so I'm thinking that when I break on loop/switch, it will break all.

Another idea is that it goes some kind of loop, but I can't figure out where it loops.

Here is my code:

void Gcode(){
  String yy,xx,gg;
  char text[64];
  int number=1;
while(number!=3){
while (Serial.available()>0) {
  delay(3);  //delay to allow buffer to fill
  char c = Serial.read();
  Serial.println(c);
  switch(c){
    case 'G':
      //read_number()
      while (Serial.available()>0) {
        char k = Serial.read();
    if(k==' ' || k=='\n'){
          break; 
    }
        else{
          gg+=k;
    }
      }
      switch(gg.toInt()){
        case 1:
        Serial.println(gg);
      while (Serial.available()>0) {
        c = Serial.read();
            Serial.println(c);
        switch(c){
          case 'X':
            while (Serial.available()>0) {
          char k = Serial.read();
            if(k==' ' || k=='\n'){
              break; 
            }
            else{
              xx+=k;
            }
            }
                char buf[xx.length()];
                xx.toCharArray(buf,xx.length());
                x2=atof(buf);
                Serial.println(x2);
                break; 
              case 'Y':
            while (Serial.available()>0) {
              char k = Serial.read();
              if(k==' ' || k=='\n'){
                break;
                  }
              else{
                    yy+=k;
              }
            }
                Serial.println(yy);
                char buf2[yy.length()];
                yy.toCharArray(buf2,yy.length());
                y2=atof(buf2);
            break;
              case 'E':
            break;
              case 'F':
            break;
              default:
            Serial.print("the end");
          }
         Serial.print("out of switch");
        }
        break;
      case 2:
        break;
      default: 
    Serial.print("nothing");
      }
      break;
    case '\n':
      number=3;
      break;
    default:
      Serial.print("default");
  }

}
}
if(sizeof(yy)>0){
  yy="";
  xx="";
  gg="";
}
Serial.print("quit");
}

When I send G1 X10.00 Y-100.00 \n It prints only: G 1 X 10.00 out of s


Solution

  • one of your big problem is that your while end when thwere are nomore carachter. This mean that if your loop consume the buffer FASTER than it get written (remeber:9600 baud mean 960Byte/s, arduino even if slow but can compute 16.000.000 operation/s...).

    Another big problem MAY bethe lack of ram, os your output is truncated. there is some function to check real time usage of ram, see http://playground.arduino.cc/Code/AvailableMemory, stopping to use String and even char array is a way better idea; the code is not that hard to write!

    so the pc would send "G1 X10.00 Y-100.00 \n" but at time X your aruino get "G1 X10.00", if you read really fast the buffer now (faster than 1/960 of a second, arduino is a way faster than that!)

    so ideally you should change all your while condition removing serial available but instead putting the condition you use in the if with the break; sothe first while from

    while (Serial.available()>0)
    

    became

    while ( (k=Serial.read()) != ' ' && k != '\n') //yes it is a bit weird like this
    

    maybe a little better, with check that k is a valid caracter, AND timeout

    unsigned long timeout_ms = 1000; //timeout after 1 seconds from NOW!
    unsigned long start_ms = millis();
    int k=Serial.read();
    while ( k != ' ' && millis()-start_ms < timeout_ms){// because here we expect "Gx ", why are you was also using k != '\n'? removed, feel free to add it back
        if (k == -1){
            k=Serial.read(); //read the next char
            continue; //return to the beginning of the while
        }
        [... do thigs...]
        k=Serial.read(); //read the next char
        //here you may add "start_ms = millis();" if you want to reset the timeout
    }