Welcome! Log In Create A New Profile

Advanced

Arduino -Bresenham - similar but different from previous thread

Posted by nwavi17 
Arduino -Bresenham - similar but different from previous thread
September 14, 2010 07:08PM
Hi there,

As with Nition this is not quite for Reprap, so apologies for posting here if not appropriate,
however there is definitely a lot of knowledge here so I hope you don't mind me asking.

Here's the scenario

I am working on an elliptical drawing machine, for a Digital Media Mres at Newcastle University in the UK.
It’s a course aimed at a wide variety of practitioners including artists which is my background.
The machine is created as an artwork, a self erasing drawing machine.

The ellipse has a single beam moving around its circumference - one motor is fixed at the end of this beam (motor1),
the other (motor2) is on linear bearings and moves up on down along the beam as the distance
between it and motor1 changes as it tracks around. A third motor moves a drawing carriage,
also on linear bearings, between these two, and with this any point within the ellipse can be reached in a variety of ways.

I have traced a handwritten sentence with the motors, (clicking by hand one step at a time - not with encoders),
saving this list of positions, a vector at a time as it were into a text file
and am now writing a program to draw this sentence over and over.

This is where Bresenham probably should come in?

Obviously there are some movements where one motor is only moving a few number of steps compared to another moving say 400 and ideally I want the smaller number of steps taking the same amount of time as the larger one.

Using Arduino for coding currently I have code that looks like this - no Bresenham or anything like it - for moving the motors:

for (int i=0; i<484; i++)
    {
      digitalWrite(dir3, HIGH);
      digitalWrite(pul3, LOW);
      delayMicroseconds(s);
      digitalWrite(pul3, HIGH);
      delayMicroseconds(s);
      
      if(i != 93)
      {
        digitalWrite(dir1, HIGH);
        digitalWrite(pul1, LOW);
        delayMicroseconds(s);
        digitalWrite(pul1, HIGH);
        delayMicroseconds(s);   
      }
      
    }

But obviously as I'm comparing the second motor to the number of steps taken (i) by the first motor
then I just get 93 steps happening at the same time before motor one just continues until it gets to it's 484.
So looking around and asking on various forums it was suggested to look at Bresenhams, but how should I implement it to work with 3 motors even when it’s still just drawing in 2D?

I’m assuming I have to add in some more elements so that I have x0, x1, x2, y0, y1, y2, but how then do I put them into the code
esp. with regards to the boolean I’ve seen used for steep which just compares two variables (at least on the code sample on wikipedia).

Any assistance or advice, code snippets etc would be fantastic,

many thanks for your time,
VDX
Re: Arduino -Bresenham - similar but different from previous thread
September 15, 2010 04:13AM
... for synchronizing your motors when driving a straight line you have to select the motor with the most steps (MAhot smileyxsteps, ysteps, zsteps)) and calculate the relation for the other motors - eg. with [move X300, Y160, Z25] motor X has to clock 300 steps, and in the same time motor Y and Z have to clock their respective steps synchronous.

So you'll calculate 300/160 = 1.875 for Y and 300/25 = 12 for Z.

Then you start to clock your X-motor and every '1.875'-th step (e.g. MODULO(xstep,1.875)) you have to clock the Y-motor, and every 12-th step the Z-motor, so you'll get a straight line between the two positions in 3D.

For drawing curves you have to divide the curve in short linear sequences and calculate the lines with linear Bresenham or apply the 'circular' Bresenham which should be somewhere in the Wiki too ...


Viktor
--------
Aufruf zum Projekt "Müll-freie Meere" - [reprap.org] -- Deutsche Facebook-Gruppe - [www.facebook.com]

Call for the project "garbage-free seas" - [reprap.org]
Re: Arduino -Bresenham - similar but different from previous thread
September 15, 2010 07:24PM

Thanks for that, much appreciated. All I need to do now is set up a function which divides the bigger step by the smaller step for whichever co-ordinate comes into the system from my array and then use them as the modulo variables to the motor switching is that correct? I attach an image and better explanation of the machine this time as well.

The machine looks like this

Point(or motor) A moves on the elliptical green rail, attached to A is a beam that can rotate around A. B also moves on the green rail, but influences the red beam only in rotation: whatever B does, the only effect is that the beam will rotate around A. Also if point A moves and point B stays stationary you get the reversal with the beam rotating around B whilst A tracks around rail.
C moves along the red beam.

The whole piece is an artwork which is continually writing the same line of text and erasing it (Point C is chalk and has a felt eraser attached behind it). Obviously there are an infinite number of was to draw a point due to the movement of C but, I’m choreographing the movement. The text is handwritten on the surface inside the ellipse, then using a program which equates specific keypresses to individual motor steps (clockwise and anti clockwise), I trace what has been written, splitting each character into a number of segments. Then in the final program each motor position in each specific segment is stored in an array. When I call an array position (carrying 3 pieces of information, 1 for each of the motors) I’d like each of the motors to start and stop at the same time regardless of the number of steps each one has, which is where the algorithm comes in.

The current code I have in Arduino looks like this (apologies for the size, but just in case people are interested and also what with the functions and all it doesn't quite make sense) - the array's I know will be too large for arduino to handle them so going to have to get Processing or something else passing the stuff through, this is just how I have it set ready to take stuff in and without Bresenham's or DDA/ the modulo thing implemented yet.
//motor pins defined
int pul1 = 3;
int dir1 = 4;
int pul2 = 5;
int dir2 = 6;
int pul3 = 7;
int dir3 = 8;
int penD = 9;

int myFramesA [2000];
int myFramesA [2000];

//limitswitch variables and pins defined
int limit1;
int switchpin1 = 11;
int limit2;
int switchpin2 = 12;

int start = 0;
int start2 = 0;
int s = 1700;
int counter = 0;

//Functions-------------------------------------------------------------------------------
void motorMoving1 (int d1, int p1)
{
  if (d1 == 0)
  {
    digitalWrite(dir1, HIGH);
  }
  
  else if (d1 == 1)
  {
    digitalWrite(dir1, LOW);
  }
  
  if (p1 == 1)
  {
    digitalWrite(pul1, LOW);
    delayMicroseconds(s);
    digitalWrite(pul1, HIGH);
    delayMicroseconds(s);
  } 
  
}

//-------------------------------------------------------------------------------
void motorMoving2 (int d2, int p2)
{
  if (d2 == 0)
  {
    digitalWrite(dir2, HIGH);
  }
  
  else if (d2 == 1)
  {
    digitalWrite(dir2, LOW);
  }
  
  if (p2 == 1)
  {
    digitalWrite(pul2, LOW);
    delayMicroseconds(s);
    digitalWrite(pul2, HIGH);
    delayMicroseconds(s);
  } 
  
}

//-------------------------------------------------------------------------------
void motorMoving3 (int d3, int p3)
{
  if (d3 == 0)
  {
    digitalWrite(dir3, HIGH);
  }
  
  else if (d3 == 1)
  {
    digitalWrite(dir3, LOW);
  }
  
  if (p3 == 1)
  {
    digitalWrite(pul3, LOW);
    delayMicroseconds(s);
    digitalWrite(pul3, HIGH);
    delayMicroseconds(s);
  } 
  
}
//-------------------------------------------------------------------------------
  void motorStartPosi()
  
{
    limit1 = digitalRead(switchpin1);
    limit2 = digitalRead(switchpin2);
    digitalWrite(dir1, LOW);
    digitalWrite(dir2, HIGH);
    //Serial.println(limit1);

    if(limit1 == 0)
  {
    digitalWrite(pul1, LOW);
    delayMicroseconds(250);
    digitalWrite(pul1, HIGH);
    delayMicroseconds(250);
  }
    
  else 
  {
      //Serial.println("bingo");
      start = 1;
      delayMicroseconds(1000);
  }
  
   if(limit2 == 0)
  {
    digitalWrite(pul2, LOW);
    delayMicroseconds(250);
    digitalWrite(pul2, HIGH);
    delayMicroseconds(250);
  }
    
  else 
  {
      //Serial.println("bingo2");
      start2 = 1;
  }
  
}


//-------------------------------------------------------------------------------
void setup()
{
  //motor pins setup
  pinMode(pul1, OUTPUT);
  pinMode(dir1, OUTPUT);
  pinMode(pul2, OUTPUT);
  pinMode(dir2, OUTPUT);
  pinMode(pul3, OUTPUT);
  pinMode(dir3, OUTPUT);
  pinMode(penD, OUTPUT);
  digitalWrite(pul1, HIGH);
  digitalWrite(dir1, HIGH);
  digitalWrite(pul2, HIGH);
  digitalWrite(dir2, LOW);
  digitalWrite(pul3, HIGH);
  digitalWrite(dir3, LOW);
  digitalWrite(penD, LOW);
  pinMode(switchpin1, INPUT);
  pinMode(switchpin2, INPUT);
}

//-------------------------------------------------------------------------------
void loop()
{
  delay(5000);  //GET TO THE 0,0, POSITION
  if(start == 0 || start2 == 0)
  {
    motorStartPosi();
  }
  
    motorMoving1(0,1); 
    motorMoving2(0,1);
    motorMoving3(0,1);
    counter++;
  
  
      if(counter == motorAMaxforThisStep)
      {
        if(counter == motorBMaxforThisStep)
         {
           if(counter == motorCMaxforThisStep)
            {
              motorMoving3(0,0);
             }
            motorMoving2(0,0);
           }
          motorMoving1(0,0);       
       }
     counter = 0;
      
  
}

If anyone has additional advice, let me know,

thanks for the help. Got given a few old plotting machines during this project one of which has some tasty motor's and ballscrews on it so after the dust has settled think a reprap may well be in order, so at least I won't be a stranger on the forums winking smiley

Re: Arduino -Bresenham - similar but different from previous thread
September 15, 2010 08:13PM
Whoops, I forgot to post that I had realised that there would be an issue with the array sizes in the code grinning smiley

The project has gone through lots of stages from the first idea Processing + Max + Arduino, then into oF due to the very cool getCharacterAsPointsCommand alas the character is a ttf right so an outline font and not ideal for my machine - downer. Then just to basics, typeface is my handwriting trace it with the actual machine and play it back.

My Uni tutor today pointed out that I probably didn't have enough segments to accurately render what was drawn - he neglected to point out the overloading of Arduino's memory by doing that though!

So, now in all likelihood the array's will be in processing and I'll be parsing them in position by position, just forgot I hadn't written or commented that in the code yet.

winking smiley
Re: Arduino -Bresenham - similar but different from previous thread
September 15, 2010 09:10PM
As with Nition this is not quite for Reprap, so apologies for posting here if not appropriate,
however there is definitely a lot of knowledge here so I hope you don't mind me asking.


No worries, as long as you promise to put an extruder on it some day. smiling bouncing smiley
VDX
Re: Arduino -Bresenham - similar but different from previous thread
September 16, 2010 04:30AM
... maybe this blog is helpfull ...


Viktor
--------
Aufruf zum Projekt "Müll-freie Meere" - [reprap.org] -- Deutsche Facebook-Gruppe - [www.facebook.com]

Call for the project "garbage-free seas" - [reprap.org]
Sorry, only registered users may post in this forum.

Click here to login