Servo don't work on CNC drawing machine HELP (processing)

Hello,

I have trouble to get the servo working.
it’s supose to move when the pen is sopose to lift or get down on the sheet.

My progect is a drawing machine.
the x and y axis work well but the servo don’t move.
i don’t know what to do, the servo isn’t broke.

when i plug the servo, the motor are louder, i don’t know why.

all the circuit are hand made.

I use processing to read the g-code and send it to the arduino with USB plug.
All the connection is ok, I think it’s a software problem but i’m not sure.

please help me,
sorry for my bad english.

arduino_CNC.ino (7.77 KB)

gcode_executer.pde (4.18 KB)

Images from Original Post so we don’t have to download them. See this Image Guide

17521862_1268212689892583_1139959515_o.jpg

17571099_1268216976558821_1364829102_o.jpg

17475123_1268216879892164_2045839828_o.jpg

…R

We know what a servo looks like and the other photos don't convey any useful info. Sorry.

How is everything powered? Make a pencil drawing showing the connections and post a photo of the drawing. Please DO NOT use Fritzing.

What are the print statements in your program telling you?

...R

Hello,

everything is powered by 4 AA battery for a total of 5.2VDC

here is the drawing i use it’s made with fritzing but it’s ok i think

circuit_schematic.jpg

Your diagram does not show where the batteries are connected.

5v is very little for stepper motors - 12v or 24v would be more usual. But that would require specialized stepper drivers that could limit the current to protect the motor.

And you have not answered the question "What are the print statements in your program telling you?"

...R Stepper Motor Basics Simple Stepper Code

the battery is connected where there is the usb port on the diagram

I know the voltage is a little bit low but it's work fine so ...

all the process going well, no error message in the console, all is working has expected except for the servo motor that just doesn't do what it's suppose to do. When I power the arduino and plug it into the computer, the servo move randomly (suppose to don't move)

for the question "What are the print statements in your program telling you?"

I don't know what do you meen if you meen the text that the program is writing in the console : the program write line by line the G-code and the motor follow but when it arrive to the command "pen up" the servo just don't move and the program continue with the next command and finish successfully (except for the servo)

patate1684: for the question "What are the print statements in your program telling you?"

The Arduino program has lots of lines with Serial.print() statements that show the progress through the program - including, for example "Pen Up" and "pen Down".

You should change this

boolean verbose = false;

to

boolean verbose = true;

...R

I change boolean verbose to true and here are the print statement and the gcode that I use to test (in text format because I can’t upload .gcode file)

printStatement(youtubeLogo).txt (14.4 KB)

Youtube Logo(Gcode).txt (3.34 KB)

It's hard, after this length of time, to remember what your problem is.

The output includes pen up and pen down messages. Does the servo move when they are posted?

...R

no it doesn't that the problem

patate1684: no it doesn't that the problem

I've lost track of this now. What program has the code in it that prints PEN UP and PEN DOWN?

...R

What program has the code in it that prints PEN UP and PEN DOWN?

the arduino program

patate1684: the arduino program

I was rather hoping you would be a bit more specific than that - maybe even post the latest version of the program so I don't have to read back over the whole Thread.

...R

the code you asking for is at the end

#include <Servo.h>
#include <Stepper.h>

#define LINE_BUFFER_LENGTH 512

const int penZUp = 80;
const int penZDown = 40;

const int penServoPin = 6;

const int stepsPerRevolution = 20; 

Servo penServo;  

Stepper myStepperY(stepsPerRevolution, 2,3,4,5);            
Stepper myStepperX(stepsPerRevolution, 8,9,10,11);  

struct point { 
  float x; 
  float y; 
  float z; 
};

struct point actuatorPos;

float StepInc = 1;
int StepDelay = 0;
int LineDelay = 50;
int penDelay = 50;

float StepsPerMillimeterX = 6.0;
float StepsPerMillimeterY = 6.0;

float Xmin = 0;
float Xmax = 40;
float Ymin = 0;
float Ymax = 40;
float Zmin = 0;
float Zmax = 1;

float Xpos = Xmin;
float Ypos = Ymin;
float Zpos = Zmax; 

boolean verbose = true;

void setup() {
  Serial.begin( 9600 );
  
  penServo.attach(penServoPin);
  penServo.write(penZUp);
  delay(200);

  myStepperX.setSpeed(250);
  myStepperY.setSpeed(250);  

  Serial.println("Mini CNC Plotter alive and kicking!");
  Serial.print("X range is from "); 
  Serial.print(Xmin); 
  Serial.print(" to "); 
  Serial.print(Xmax); 
  Serial.println(" mm."); 
  Serial.print("Y range is from "); 
  Serial.print(Ymin); 
  Serial.print(" to "); 
  Serial.print(Ymax); 
  Serial.println(" mm."); 
}

void loop() 
{
  delay(200);
  char line[ LINE_BUFFER_LENGTH ];
  char c;
  int lineIndex;
  bool lineIsComment, lineSemiColon;

  lineIndex = 0;
  lineSemiColon = false;
  lineIsComment = false;

  while (1) {

    while ( Serial.available()>0 ) {
      c = Serial.read();
      if (( c == '\n') || (c == '\r') ) {             
        if ( lineIndex > 0 ) {                        
          line[ lineIndex ] = '\0';                   
          if (verbose) { 
            Serial.print( "Received : "); 
            Serial.println( line ); 
          }
          processIncomingLine( line, lineIndex );
          lineIndex = 0;
        } 
        else { 
          
        }
        lineIsComment = false;
        lineSemiColon = false;
        Serial.println("ok");    
      } 
      else {
        if ( (lineIsComment) || (lineSemiColon) ) {   // Throw away all comment characters
          if ( c == ')' )  lineIsComment = false;     // End of comment. Resume line.
        } 
        else {
          if ( c <= ' ' ) {                           // Throw away whitepace and control characters
          } 
          else if ( c == '/' ) {                    // Block delete not supported. Ignore character.
          } 
          else if ( c == '(' ) {                    // Enable comments flag and ignore all characters until ')' or EOL.
            lineIsComment = true;
          } 
          else if ( c == ';' ) {
            lineSemiColon = true;
          } 
          else if ( lineIndex >= LINE_BUFFER_LENGTH-1 ) {
            Serial.println( "ERROR - lineBuffer overflow" );
            lineIsComment = false;
            lineSemiColon = false;
          } 
          else if ( c >= 'a' && c <= 'z' ) {        // Upcase lowercase
            line[ lineIndex++ ] = c-'a'+'A';
          } 
          else {
            line[ lineIndex++ ] = c;
          }
        }
      }
    }
  }
}

void processIncomingLine( char* line, int charNB ) {
  int currentIndex = 0;
  char buffer[ 64 ];                                 // Hope that 64 is enough for 1 parameter
  struct point newPos;

  newPos.x = 0.0;
  newPos.y = 0.0;

  //  Needs to interpret 
  //  G1 for moving
  //  G4 P300 (wait 150ms)
  //  G1 X60 Y30
  //  G1 X30 Y50
  //  M300 S30 (pen down)
  //  M300 S50 (pen up)
  //  Discard anything with a (
  //  Discard any other command!

  while( currentIndex < charNB ) {
    switch ( line[ currentIndex++ ] ) {              // Select command, if any
    case 'U':
      penUp(); 
      break;
    case 'D':
      penDown(); 
      break;
    case 'G':
      buffer[0] = line[ currentIndex++ ];          // /!\ Dirty - Only works with 2 digit commands
      //      buffer[1] = line[ currentIndex++ ];
      //      buffer[2] = '\0';
      buffer[1] = '\0';

      switch ( atoi( buffer ) ){                   // Select G command
      case 0:                                   // G00 & G01 - Movement or fast movement. Same here
      case 1:
        // /!\ Dirty - Suppose that X is before Y
        char* indexX = strchr( line+currentIndex, 'X' );  // Get X/Y position in the string (if any)
        char* indexY = strchr( line+currentIndex, 'Y' );
        if ( indexY <= 0 ) {
          newPos.x = atof( indexX + 1); 
          newPos.y = actuatorPos.y;
        } 
        else if ( indexX <= 0 ) {
          newPos.y = atof( indexY + 1);
          newPos.x = actuatorPos.x;
        } 
        else {
          newPos.y = atof( indexY + 1);
          indexY = '\0';
          newPos.x = atof( indexX + 1);
        }
        drawLine(newPos.x, newPos.y );
        //        Serial.println("ok");
        actuatorPos.x = newPos.x;
        actuatorPos.y = newPos.y;
        break;
      }
      break;
    case 'M':
      buffer[0] = line[ currentIndex++ ];        // /!\ Dirty - Only works with 3 digit commands
      buffer[1] = line[ currentIndex++ ];
      buffer[2] = line[ currentIndex++ ];
      buffer[3] = '\0';
      switch ( atoi( buffer ) ){
      case 300:
        {
          char* indexS = strchr( line+currentIndex, 'S' );
          float Spos = atof( indexS + 1);
          //          Serial.println("ok");
          if (Spos == 30) { 
            penDown(); 
          }
          if (Spos == 50) { 
            penUp(); 
          }
          break;
        }
      case 114:                                // M114 - Repport position
        Serial.print( "Absolute position : X = " );
        Serial.print( actuatorPos.x );
        Serial.print( "  -  Y = " );
        Serial.println( actuatorPos.y );
        break;
      default:
        Serial.print( "Command not recognized : M");
        Serial.println( buffer );
      }
    }
  }



}



void drawLine(float x1, float y1) {

  if (verbose)
  {
    Serial.print("fx1, fy1: ");
    Serial.print(x1);
    Serial.print(",");
    Serial.print(y1);
    Serial.println("");
  }  

  
  if (x1 >= Xmax) { 
    x1 = Xmax; 
  }
  if (x1 <= Xmin) { 
    x1 = Xmin; 
  }
  if (y1 >= Ymax) { 
    y1 = Ymax; 
  }
  if (y1 <= Ymin) { 
    y1 = Ymin; 
  }

  if (verbose)
  {
    Serial.print("Xpos, Ypos: ");
    Serial.print(Xpos);
    Serial.print(",");
    Serial.print(Ypos);
    Serial.println("");
  }

  if (verbose)
  {
    Serial.print("x1, y1: ");
    Serial.print(x1);
    Serial.print(",");
    Serial.print(y1);
    Serial.println("");
  }

  //  Convert coordinates to steps
  x1 = (int)(x1*StepsPerMillimeterX);
  y1 = (int)(y1*StepsPerMillimeterY);
  float x0 = Xpos;
  float y0 = Ypos;

  //  Let's find out the change for the coordinates
  long dx = abs(x1-x0);
  long dy = abs(y1-y0);
  int sx = x0<x1 ? StepInc : -StepInc;
  int sy = y0<y1 ? StepInc : -StepInc;

  long i;
  long over = 0;

  if (dx > dy) {
    for (i=0; i<dx; ++i) {
      myStepperX.step(sx);
      over+=dy;
      if (over>=dx) {
        over-=dx;
        myStepperY.step(sy);
      }
      delay(StepDelay);
    }
  }
  else {
    for (i=0; i<dy; ++i) {
      myStepperY.step(sy);
      over+=dx;
      if (over>=dy) {
        over-=dy;
        myStepperX.step(sx);
      }
      delay(StepDelay);
    }    
  }

  if (verbose)
  {
    Serial.print("dx, dy:");
    Serial.print(dx);
    Serial.print(",");
    Serial.print(dy);
    Serial.println("");
  }

  if (verbose)
  {
    Serial.print("Going to (");
    Serial.print(x0);
    Serial.print(",");
    Serial.print(y0);
    Serial.println(")");
  }

  
  delay(LineDelay);
  
  Xpos = x1;
  Ypos = y1;
}


void penUp() { 
  penServo.write(penZUp); 
  delay(LineDelay); 
  Zpos=Zmax; 
  if (verbose) { 
    Serial.println("Pen up!"); 
  } 
}
void penDown() { 
  penServo.write(penZDown); 
  delay(LineDelay); 
  Zpos=Zmin; 
  if (verbose) { 
    Serial.println("Pen down."); 
  } 
}

I am no expert on the L293D (I don't have any) but it looks to me from your diagram in Reply #3 that you have no 5v power supply connected to the wires connected to the servo.

If that does not suggest a solution I recommend that you make a copy of your program and strip everything out except the servo code and use the cut-down program to debug the problem.

...R

ok thank you very much for your time, I will try that :)