processing example controlling stepper x y

Hi
I am working on making a large (4m by 4m) plotter with 2 steppers controlling x and y for an installation

I am fine with the arduino side of making the hardware and programming etc.

I dont really know much about "processing" but was wondering if anyone had used processing to drive steppers, drawing images similar to the "drawbot" or other xy plotter devices.

Any processing and arduino code examples from similar projects would be useful to start me off.

This is code that I've used (and shared) to move stepper motors in response to mouse movements in Processing.

The Processing code:

import processing.serial.*;

Serial myPort;         // The serial port
PFont fontA;
boolean ready = false; // Whether we've heard 
                       // from the microcontroller
String reply = "No reply";

void setup() 
{
  size(400, 400);
  background(0);
  smooth();
  // Load the font. Fonts must be placed within the data 
  // directory of your sketch. A font must first be created
  // using the 'Create Font...' option in the Tools menu.
  fontA = loadFont("CourierNew-12.vlw");
  textAlign(LEFT);

  // Set the font and its size (in units of pixels)
  textFont(fontA, 24);

  // Print a list of the serial ports, for debugging purposes:
  println(Serial.list());

  // I know that the first port in the serial list on my mac
  // is always my  FTDI adaptor, so I open Serial.list()[0].
  // On Windows machines, this generally opens COM1.
  // Open whatever port is the one you're using.
  String portName = Serial.list()[0];
  myPort = new Serial(this, portName, 9600);
}

void draw() 
{
  background(0);
  
  int xNow = mouseX - 200;
  int yNow = 200 - mouseY;
  
  String xStg = str(xNow * 2);
  String yStg = str(yNow * 2);
  
  String msg = "X: " + xStg;
  text(msg, 10, 100);
  
  msg = "Y: " + yStg;
  text(msg, 10, 200);
  
  if(ready)
  {
    msg = "[X:" + xStg + ",Y:" + yStg + "]";
    myPort.write(msg);
//    print("Sent: ");
//    println(msg);
    ready = false;
    
//    text(reply, 10, 300);
  }
}

void serialEvent(Serial myPort)
{
  // read a byte from the serial port:
  char inChar = myPort.readChar();
  print(inChar);
  
  // if this is the first byte received, and it's an R,
  // clear the serial buffer and note that you've
  // had first contact from the microcontroller. 
  // Otherwise, add the incoming byte to the array:
  if (ready == false)
  {
    if (inChar == 'G')
    { 
      myPort.clear();   // clear the serial port buffer
      ready = true;     // you've had first contact 
    }
  }
}

And the Arduino code:

int xDirPin = 6;
int xStpPin = 7;
int yDirPin = 11;
int yStpPin = 12;

char inData[15];
int inPos = 0;
int xPos = 0;
int yPos = 0;
int xVal = 0;
int yVal = 0;
int xScl = 1;
int yScl = 1;
int dx = 0;
int dy = 0;

void setup()
{
  pinMode(xDirPin, OUTPUT);
  pinMode(xStpPin, OUTPUT);
  pinMode(yDirPin, OUTPUT);
  pinMode(yStpPin, OUTPUT);
  
  Serial.begin(9600);
}

void stepX(boolean dir, int steps)
{
  digitalWrite(xDirPin, dir);
  delay(50);
  Serial.println("Stepping in X");
  for(int i=0; i<steps; i++)
  {
    digitalWrite(xStpPin, HIGH);
    delayMicroseconds(100);
    digitalWrite(xStpPin, LOW);
    delayMicroseconds(100);
  }
}

void stepY(boolean dir, int steps)
{
  digitalWrite(yDirPin, dir);
  delay(50);
  Serial.println("Stepping in Y");
  for(int i=0; i<steps; i++)
  {
    digitalWrite(yStpPin, HIGH);
    delayMicroseconds(100);
    digitalWrite(yStpPin, LOW);
    delayMicroseconds(100);
  }
}

void loop()
{
  // Tell sender that we're ready
  Serial.println("G");
  xScl = 1;
  yScl = 1;
  
  // Wait for the sender to send
  while(Serial.available() == 0)
  {
  }
  
  // Read what the sender sent
  char val = ' ';
  while(Serial.available() > 0 && val != ']')
  {
    val = Serial.read();
//    Serial.print(val);
    
    // If this is the start of the data...
    if(val == '[')
    {
      inPos = 0;
      inData[inPos] = '\0';
      
      // read to the end of the data
      while(val != ']' && inPos < 15)
      {
        // Wait for data to be available
        while(Serial.available() == 0)
        {
        }
        
        // Reaqd the next letter
        val = Serial.read();
//        Serial.print(val);
        if(val != ']')
        {
          inData[inPos] = val;
          inPos++;
          inData[inPos] = '\0';
        }
      }
    }
  }
  
  if(inPos > 0)
  {
//    Serial.println();
//    Serial.print("Read: [");
//    Serial.print(inData);
//    Serial.println("]");
    
    int numVals = sscanf(inData, "X:%d,Y:%d", &xVal, &yVal);
//    Serial.print("Number of values parsed: ");
//    Serial.println(numVals, DEC);
//    Serial.print("xVal: ");
//    Serial.println(xVal, DEC);
//    Serial.print("yVal: ");
//    Serial.println(yVal, DEC);
  }

  dx = (xVal * xScl) - xPos;
  dy = (yVal * yScl) - yPos;
    
  xPos = xVal;
  yPos = yVal;
  
  if(dx > 0)
    stepX(true, dx);
  else
    stepX(false, -dx);
  
  if(dy > 0)
    stepY(true, dy);
  else
    stepY(false, -dy);
  delay(50);
}

you might want to put a larger delay in that loop
most steppers won't step that fast!

Hey PaulS.

Almost total Noob here but educating myself for a project along the lines of what´s above.

Any more documenatation of your experience controlling steppers on an XY grid through Processing?

I will eventually want to upload a standalone sequence to Arduino for a path to be repeated many times but would like to sketch it graphically in Processing...

Thanks for any input!

Any more documenatation of your experience controlling steppers on an XY grid through Processing?

When I switched to larger stepper motors, some smoke escaped from the motor controller board. I haven't been able to get it all back in, yet.

That code would be a good starting point, then. Create the sketch in Processing, and a button. When the button is clicked, send the sketch points, one line at a time, to the Arduino.

I'm not sure how you would be able to erase a mistake, though. I've used other languages to try to write a decent sketching application. The relationship between a bunch of pixels lit up on the screen and a known element (line, circle, polygon, etc.) is the hardest relationship to define. Selecting an object means knowing what pixels go with what object. Particularly difficult when two objects overlap. Do you pick the one on top? To do that, you need to know the order that the elements are drawn.

Scaling, panning, and rotating (if you want to support 3D) complicate matters considerably.

OpenGL handles many of the drawing issues (panning, scaling, rotating), and the what-pixel-goes-with-what-element selection issues. It has a rather steep learning curve, but is integrated with many higher level application development environments, like Windows forms.

Thanks for replying, sorry for the smoke!

I'm starting to think that GCode might be the way to go...

Will post back in case of sucessess.

Best.
H