Pages: [1]   Go Down
Author Topic: Need help interfacing my Plotter with Processing  (Read 1318 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello everyone

I've built a nice little x/y plotter (http://bit.ly/1kg2nv6) with 2 stepper motors that "prints" 128x128 bitmap images.
Right now, as you can see in the code, the Image is stored as bytes in a huge 2d array.
I would like a way to use Processing to import a 128x128 png image, convert it to a binary image, and then send it to the arduino via serial connection.
Sadly i'm a huge noob in processing and serial connections and also couldn't find anything on the internet that does such a thing. Could someone please help me create the processing application and change the arduino code?

thanks in advance
dabre
ps.: sorry for my bad english , i'm swiss.

this is my code:
Code:
#include <Stepper.h>
#include <avr/pgmspace.h>

#define STEPS 48

int penPlusA = 10;
int penPlusB = 11;
int penMinusA = 12;
int penMinusB = 13;

Stepper stepperX(STEPS, 0,1,2,3);
Stepper stepperY(STEPS, 4,5,6,7);

int limitPin = 8;
int stopSwitch = 9;

int x_inc = 0;
int y_inc = 0;
int z_pos = 0;

int stepSizeX = 6;//max 8
int stepSizeY = round(stepSizeX*1.6);

int maxSteps = 1075;
int homePos = (maxSteps/2)-((128*stepSizeX)/2);

String color = "color";// color, draft, line, square or cross
int motorSpeed = 280;

const byte image[128][128] PROGMEM = //insert image here, I deleted the array definition because the code would be too big
{};

void setup()
{
  if(homePos<0){homePos = 0;}
  
  if(color == "square" ){motorSpeed = 200;}else if(color == "draft" || color == "line"){motorSpeed = 300;}
  
  stepperX.setSpeed(motorSpeed);
  stepperY.setSpeed(motorSpeed);

  pinMode(penPlusA, OUTPUT);    
  pinMode(penPlusB, OUTPUT);    
  pinMode(penMinusA, OUTPUT);    
  pinMode(penMinusB, OUTPUT);    
  
  pinMode(limitPin, INPUT);
  digitalWrite(limitPin, HIGH);
  
  pinMode(stopSwitch, INPUT);
  digitalWrite(stopSwitch, HIGH);
  
  Serial.begin(9600);
  
  delay(2000);
}

void loop()
{
  goHome();
  draw();
  while(1){
  }

}


void penDown()
{

  if (z_pos == 0){
    digitalWrite(penPlusA, HIGH);
    digitalWrite(penPlusB, HIGH);
    digitalWrite(penMinusA, LOW);
    digitalWrite(penMinusB, LOW);
    delay(500);              
    digitalWrite(penPlusA, LOW);
    digitalWrite(penPlusB, LOW);
    digitalWrite(penMinusA, LOW);
    digitalWrite(penMinusB, LOW);

    z_pos = 100;
  }
}

void penUp()
{
  if(z_pos == 100){
    digitalWrite(penPlusA, LOW);
    digitalWrite(penPlusB, LOW);
    digitalWrite(penMinusA, HIGH);
    digitalWrite(penMinusB, HIGH);
    delay(500);
    digitalWrite(penPlusA, LOW);  
    digitalWrite(penPlusB, LOW);  
    digitalWrite(penMinusA, LOW);  
    digitalWrite(penMinusB, LOW);  

    z_pos = 0;
  }
}

void colorIn(int dir){
  penDown();
  for(int i = 0;i<stepSizeX;i+=1){
    if(i%2 == 0){
      stepperY.step(stepSizeY);
    }
    else{
      stepperY.step(-stepSizeY);
    }
    stepperX.step(1*dir);
  }
}

void sqr(int dir){
  penUp();
  stepperX.step(stepSizeX*dir);
  penDown();
  stepperY.step(stepSizeY);
  stepperX.step(-stepSizeX*dir);
  stepperY.step(-stepSizeY);
  stepperX.step(stepSizeX*dir);
}

void draft(int dir){
  penDown();
  for(int i = 0;i<2*stepSizeX;i++){
    if (i%2 == 0){
      stepperY.step(1);
    }else{
      stepperX.step(1*dir);
    }
  }
  //penUp();
  stepperY.step(-stepSizeX);
}

void line(int dir){
  penDown();
  stepperX.step(round(stepSizeX*dir));
}

void cross(int dir){
  penDown();
  for(int i = 0;i<2*stepSizeX;i++){
    if (i%2 == 0){
      stepperY.step(1);
    }else{
      stepperX.step(1*dir);
    }
  }
  penUp();
  stepperX.step(-stepSizeX*dir);
  penDown();
  for(int i = 0;i<2*stepSizeX;i++){
    if (i%2 == 0){
      stepperY.step(-1);
    }else{
      stepperX.step(1*dir);
    }
  }
  delay(50);
}

void goHome(){
  while(digitalRead(limitPin) == HIGH){
    stepperX.step(-1);
  }
  stepperX.step(homePos);
}

void draw(){
  for(int row = 0; row < 128; row+=2) {

    penUp();

    stepperX.step(-x_inc);
    x_inc = 0;  

    for(int column = 0; column < 128; column++){
      int pixel = pgm_read_byte(&(image[row][column]));
      int thisDir = 1;
      
      if(digitalRead(stopSwitch) == 0){
        while(digitalRead(stopSwitch) == 0){
          penUp();
          delay(10);
        }
      }
      Serial.println(String(row) +"," + String(column) + "," +String(pixel));
      if(pixel == 1){

        if(color == "color"){colorIn(thisDir);}
        else if(color == "square"){sqr(thisDir);}
        else if (color == "draft"){draft(thisDir);}
        else if(color == "line"){line(thisDir);}
        else{cross(thisDir);}
        
        x_inc += stepSizeX;
      }
      else{
        penUp();

        stepperX.step(stepSizeX);
        x_inc += stepSizeX;
      }
    }
    penUp();
    stepperY.step(stepSizeY);
    y_inc += stepSizeY;
    delay(15);
    
    for(int column = 127; column >= 0; column--){
      int pixel = pgm_read_byte(&(image[row+1][column]));
      int thisDir = -1;
      
      if(digitalRead(stopSwitch) == 0){
        while(digitalRead(stopSwitch) == 0){
          penUp();
          delay(stepSizeX);
        }
      }
      Serial.println(String(row+1) +"," + String(column)) + "," +String(pixel);
      if(pixel == 1){

        if(color == "color"){colorIn(thisDir);}
        else if(color == "square"){sqr(thisDir);}
        else if (color == "draft"){draft(thisDir);}
        else if(color == "line"){line(thisDir);}
        else{cross(thisDir);}
        
        x_inc -= stepSizeX;
      }
      else{
        penUp();

        stepperX.step(-stepSizeX);
        x_inc -= stepSizeX;
      }
    }

    penUp();

    stepperY.step(stepSizeY);
    y_inc += stepSizeY;
    delay(15);
  }

  penUp();

  stepperX.step(-x_inc);
  stepperY.step(5*stepSizeY);
}
« Last Edit: January 03, 2014, 01:36:35 pm by mackintoshli » Logged

UK
Offline Offline
Faraday Member
**
Karma: 101
Posts: 6135
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm guessing you have the "while(1)" in your code so that it just plots a picture once. If you only want "goHome()" and "draw()" to run once just put them in setup() and leave loop() empty.

I don't know processing but, if it doesn't have a standard way to convert a PNG to a BMP file I would do that with some external program rather than try to write your own.

Sending the data to the Arduino should be straightforward. I suggest you try sending some simple stuff first until you learn how to do it.

When you know how to send data you will need to decide how the organize the order and quantity of data that is sent so that it is in the order the plotter expects and so that it gets data as it needs it. I haven't studied your plotting system to figure out how it relates the data to the plotting - is it sufficient to have the X and Y value of a particular point and does it work row by row or column by column?

Interesting project.

...R
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The plotting system works row by row in 2 for loops, the first iterates over all the rows, the second one over each column for each row. this gives me the x/y byte to plot.

i think you could send the image row by row when the arduino asks for it:

arduino: row 1?
processing: {0,1,0,0,1,0,1,1}

so on and so forth, until the whole image is sent.
the processing application should also be able to set the step size and the color variable

Of course, the imported image could also be a 128x128 bmp file...
Logged

UK
Offline Offline
Faraday Member
**
Karma: 101
Posts: 6135
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That sounds practical.

If each pixel is represented by a 1 or 0 you could use a single byte to represent 8 pixels which would reduce the amount of bytes to be transmitted and reduce the memory requirement in the Arduino.

And I guess if you only have to store a single row in the Arduino you can probably work with larger images if you want to.

Would it matter if there was a pause at the end of each row?

...R
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

That would definitely not matter, as the plotter/printer is slow anyways smiley-lol
Logged

Pakistan
Offline Offline
Sr. Member
****
Karma: 6
Posts: 357
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Okay.. but you can convert binary into Hexadecimal and send these hexadecimal as  CHARACTER (Extended ASCII) to Arduino. This will further simplify your problem. But mind, serial data processing needs a protocol so that no garbage interfere during transportation of binary from Processing to Arduino etc.
I am using my DIY GRAPHICAL WATERFALL with same protocol.you can search at Arduino forum
Logged


UK
Offline Offline
Faraday Member
**
Karma: 101
Posts: 6135
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sending binary data is much more efficient than sending human-readable characters. For example 253 takes a single binary byte, three decimal characters or two hex characters (FD).

...R
Logged

Pakistan
Offline Offline
Sr. Member
****
Karma: 6
Posts: 357
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I am very newbie, but i think the computer can not send the binary to Arduino. If computer send 1 then the arduino will consider as a byte.. I don't know much about
Logged


UK
Offline Offline
Faraday Member
**
Karma: 101
Posts: 6135
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

There should be functions in your PC programming language that can create a byte from a number expressed as a string such as "57".

...R
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
but i think the computer can not send the binary to Arduino.
Mine can.
Logged

Pakistan
Offline Offline
Sr. Member
****
Karma: 6
Posts: 357
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Paul,
Yes my bad.. every computer can smiley.. here is your informative reply
http://forum.arduino.cc/index.php/topic,39199.0.html
« Last Edit: January 13, 2014, 10:02:26 am by Khalid » Logged


Pages: [1]   Go Up
Jump to: