9 minute read

4.2DETAILSOFIDE

The Arduino IDE (Integrated Development Environment) is a software tool used for programming and uploading code to Arduinoboards.Itisanopen-sourceplatform,availablefor freeonvariousoperatingsystemslikeWindows,macOS,andLinux.

To create a DIY drawing robot using Arduino, you would first need to gather the necessary hardware components such as an Arduino board (e.g., Arduino UNO), servo motors, a drawing tool(e.g.,pen),andafewothermaterialslikepaper,tape,andscrews.

Advertisement

Once the robot is assembled, we can use theArduinoIDEtowriteanduploadcodethatcontrols therobot'smovementsanddrawingoperations.Herearethebasicsteps:

1. ConnectyourArduinoboardtoyourcomputerusingaUSBcable.

2. OpentheArduinoIDEandcreateanewsketch(File>New).

3. Write the code (2Stepper.ino) that controls the movements of the robot's servo motors, suchasmovingthepenupanddown,andleftandright.

4. Write the code(Walldrawdemo.ino) that controlsthedrawingoperations,suchasdrawing linesorshapes.

5. UploadthecodetotheArduinoboardbyclickingonthe"Upload"buttonintheIDE.

6. Once the code is uploaded, disconnect the USBcablefromtheboardandpoweritwitha batteryorexternalpowersource.

Hence, by following these steps, by using Arduino IDE we create the working model of DIY DrawingRobot.

5.3PROGRAMCODE

1. 2Stepper.ino

The function of this project is to make the stepper motor work and make a pendulum graph.

#include <AccelStepperh>

#include <MultiStepper.h>

//Wall painting machine without servo test program This program only test 2 stepper motors, draw curve pattern, modify the parameters can change the pattern size and style.

#include <AccelStepperh>

//This lib library file is in the package, you need to copy it to the \libraries folder of arduiino first.

//Method 1: Copy it to My Documents\Arduino\libraries

// Method 2: In the menu of arduino IDE, select Project->Load Libraries->Manage Libraries and search for AccelStepper to install it automatically

#define FULLSTEP 4

#define HALFSTEP 8

//Wiring method

//wiring method of motor1

#define motorPin1 2 // 28BYJ48 pin 1 connect to arduino's 2# port

#define motorPin2 3 // 28BYJ48 pin 2 connects to 3#

#define motorPin3 5 // 28BYJ48 pin 3 connects to 5#! Note that port 4# is reserved for sd card reader

#define motorPin4 6 // 28BYJ48 pin 4 to 6#!

// Motor 2 connection

#define motorPin5 7 // 28BYJ48 pin 1 to 7#

#define motorPin6 8 // 28BYJ48 pin 2 to 8#

#define motorPin7 9 // 28BYJ48 pin 3 to 9#

#define motorPin8 10 // 28BYJ48 pin 4 connect 10#

#define stp1 279 //

#define stp2 673 // Modify this parameter, you can change the size and style of the pattern, the larger the value the larger the pattern, the larger the gap the more complex The pattern is closed after reaching the least common multiple of 2 numbers

AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4); AccelStepper stepper2(HALFSTEP, motorPin5, motorPin7, motorPin6, motorPin8); void setup() { Serial begin(9600); stepper1 setMaxSpeed(800 0); //maximum speed, too high torque becomes small, more than 256 easy to lose steps stepper1.setAcceleration(200.0); //acceleration, try to stabilize the program can be adjusted. stepper1 setSpeed(50); //speed

// depending on FULLSTEP or HALFSTEP, 1024 or 512 stepper motors turn one week

//set the number of rotation steps of motor1 Adjustable (the larger the number, the larger the graphic size) stepper1.moveTo(stp1); stepper2 setMaxSpeed(800 0); stepper2.setAcceleration(200.0); stepper2 setSpeed(50);

//same as stepper1 stepper2.moveTo(stp2); void loop() { if(stepper1 distanceToGo() == 0) stepper1 moveTo(-stepper1 currentPosition()); if(stepper2.distanceToGo() == 0) stepper2 moveTo(-stepper2 currentPosition()); stepper1.run(); stepper2 run();

// This program loops infinitely and never ends

2. WallDrawDemo.ino

Thisisthemainprogramwhichwilldrawafewprogramsfortesting.

#include <TinyStepper 28BYJ 48 h>

#include <Servo.h>

//debug code flags, remove comments, can output debug information (the program will run slowly)

//#define VERBOSE (1)

//debug flag

#define STEPS PER TURN (2048) // stepper motor one week step length 2048 steps turn 360 degrees

#define SPOOL DIAMETER (35) //spool diameter in mm

#define SPOOL CIRC (SPOOL DIAMETER * 3 1416) //Spool circumference 35*3 14=109 956

#define TPS (SPOOL CIRC / STEPS PER TURN) //Stepper motor step distance, minimum resolution

Distance per step the bobbin is pulled 0.053689mm

#define step delay 1 // waiting time for each step of the stepper motor (subtle)

#define TPD 300 //Turn waiting time (milliseconds), due to inertia the pen will continue to move, tentatively wait for the pen to come to a standstill before moving 26

//rotation direction of the two motors 1 forward - 1 reverse //adjust the in/out direction can be reversed vertically image

#define M1 REEL OUT 1 //Release line

#define M1 REEL IN -1 //Reel in line

#define M2 REEL OUT -1 //Release line

#define M2 REEL IN 1 //involved line static long laststep1, laststep2;

//when the length of the front line records the pen position

#define X SEPARATION 150 //The horizontal distance above the two ropes (mm

#define LIMXMAX ( X SEPARATION*0 5) //x-axis maximum value 0 bit in the center of the drawing board

#define LIMXMIN (-X SEPARATION*0 5) //x-axis minimum

/* Vertical distance parameters: positive values under the drawing board, theoretically as long as the drawing board is large enough can be infinite, negative value area in the pen (before opening) above */

#define LIMYMAX (-100) //y-axis maximum value at the bottom of the drawing board

#define LIMYMIN (100) //y-axis minimum value uppermost of the drawing board The vertical distance from the fixed point of the left and right lines to the pen, try to measure the placement accurately, the error is too large to have distortion

//value shrink the drawing becomes long and thin, the value increases the drawing becomes short and fat

// lift the pen servo angle parameters specific value depends on the placement of the swing arm, need to adjust

#define PEN UP ANGLE 65 //the lift pen

#define PEN DOWN ANGLE 80 // Drop the pen //The above is the parameter to be adjusted

#define PEN DOWN 1 //Pen status Down pen

#define PEN UP 0 //Pen state Raise pen struct point { float x; float y; float z; }; struct point actuatorPos; // plotter position pen position static float posx; static float posy; static float posz; // pen state static float feed rate = 0; static int ps;

// pen state Pen state (pen lift, pen drop).

/* The following are G-code communication parameters */

#define BAUD (115200) // serial port rate, used to transfer G-code or debugging optional 9600, 57600, 115200 or other common rates

#define MAX BUF (64) //Serial buffer size

Servo pen;

TinyStepper 28BYJ 48 m1; //(7,8,9,10); //M1 L stepper motor in1~4 ports corresponding to UNO 7 8 9 10

TinyStepper 28BYJ 48 m2; //(2,3,5,6); //M2 R stepper motor in1~4 ports corresponds to UNO 2 3 5 6

// Forward motion calculation - convert L1, L2 length to XY coordinates

// Use the law of cosines, theta = acos((a*a+b*b-c*c)/(2*a*b));

// find the angle between M1M2 and M1P, where P is the position of the pen void FK(float l1, float l2,float &x,float &y) { float a=l1 * TPS; float b=X SEPARATION; float c=l2 * TPS;

// Method 1 float theta = acos((a*a + b*b - c*c)/(2 0*a*b)); x = cos(theta)*l1 + LIMXMIN; y = sin(theta)*l1 + LIMYMIN;

// Method 2

/* float theta = (a*a + b*b - c*c)/(2 0*a*b); x = theta*l1 + LIMXMIN; y = sqrt (1 0 - theta * theta ) * l1 + LIMYMIN;*/

//reverse motion - convert XY coordinates to length L1, L2 void IK(float x,float y,long &l1, long &l2) { float dy = y - LIMYMIN; float dx = x - LIMXMIN; l1 = round(sqrt(dx*dx+dy*dy) / TPS); dx = x - LIMXMAX; l2 = round(sqrt(dx*dx+dy*dy) / TPS);

// Pen state void pen state(int pen st) { if(pen st==PEN DOWN) { ps=PEN DOWN ANGLE;

// Serial println("Pen down");

} else { ps=PEN UP ANGLE;

// Serial println("Pen up"); } pen write(ps); void pen down()

{ if (ps==PEN UP ANGLE) { ps=PEN DOWN ANGLE; pen write(ps); delay(TPD);

} void pen up()

{ if (ps==PEN DOWN ANGLE) { ps=PEN UP ANGLE; pen write(ps);

// Debug code serial output machine status void where() {

Serial.print("X,Y= ");

Serial print(posx);

Serial print(",");

Serial.print(posy);

Serial print("\t");

Serial print("Lst1,Lst2= ");

Serial print(laststep1); Serial print(",");

Serial println(laststep2); Serial println(""); }

// returns angle of dy/dx as a value from 0 2PI static float atan3(float dy, float dx) { float a = atan2(dy, dx); if (a < 0) a = (PI * 2 0) + a; return a;

// instantly move the virtual plotter position // does not validate if the move is valid static void teleport(float x, float y) { posx = x; posy = y; long l1,l2; IK(posx, posy, l1, l2); laststep1 = l1; laststep2 = l2;

//ref ---- slash program void moveto(float x,float y) {

#ifdef VERBOSE

Serial println("Jump in line() function");

Serial print("x:");

Serial print(x);

Serial.print(" y:");

Serial println(y);

#endif long l1,l2; IK(x,y,l1,l2); long d1 = l1 - laststep1; long d2 = l2 - laststep2;

#ifdef VERBOSE

Serial print("l1:");

Serial print(l1);

Serial print(" laststep1:");

Serial.print(laststep1);

Serial print(" d1:");

Serial println(d1);

Serial.print("l2:");

Serial print(l2);

Serial print(" laststep2:");

Serial print(laststep2);

Serial print(" d2:");

Serial println(d2);

#endif long ad1=abs(d1); long ad2=abs(d2); int dir1=d1>0 ? M1 REEL IN : M1 REEL OUT; int dir2=d2>0 ? M2 REEL IN : M2 REEL OUT; long over=0; long i; if(ad1>ad2) { for(i=0;i<ad1;++i) { m1 moveRelativeInSteps(dir1); over+=ad2; if(over>=ad1) { over-=ad1; m2 moveRelativeInSteps(dir2); } delayMicroseconds(step delay); for(i=0;i<ad2;++i) { m2 moveRelativeInSteps(dir2); over+=ad1; if(over>=ad2) { over-=ad2; m1 moveRelativeInSteps(dir1);

} delayMicroseconds(step delay);

} laststep1=l1; laststep2=l2; posx=x; posy=y;

//long distance movement will take a circular trajectory, so the long line will be cut into a short line to maintain a straight form static void line safe(float x,float y) { // split up long lines to make them straighter? float dx=x-posx; float dy=y-posy; float len=sqrt(dx*dx+dy*dy); if(len<=TPS) { moveto(x,y); return;

// too long! long pieces=floor(len/TPS); float x0=posx; float y0=posy; float a; for(long j=0;j<=pieces;++j) { a=(float)j/(float)pieces; moveto((x-x0)*a+x0,(y-y0)*a+y0); } moveto(x,y); static void help() {

Serial println(F("== Wall Drawing Machine https://github com/shihaipeng03/Walldraw =="));

Serial.println(F(" ")); } void line(float x,float y)

{ line safe(x,y);

// butterfly curve void butterfly curve(int xx,int yy,int lines,int x scale,int y scale)

//xx,yy butterfly center position, lines number of circles, more complex x scale, y scale xy axis magnification ratio { float xa,ya,p,e; pen up(); moveto(xx,yy + y scale * 0.71828); pen down(); for(float i=0;i<6.28*lines;i+=3.14/90) p=pow(sin(i/12),5); e=pow(2.71828,cos(i)); xa=x scale * sin(i) * (e - 2*cos(4*i) + p); ya=y scale * cos(i) * (e - 2*cos(4*i) + p); line safe(xa+xx,ya+yy); } pen up();

//

Peach heart curve void heart curve(int xx,int yy,float x scale,float y scale)

//xx,yy the center of the peach heart curve, x scale, y scale the magnification scale of the xy axis float xa,ya; pen up(); moveto(xx,yy+y scale * 7); pen down(); for(float i=0;i<=6 28;i+=3 14/180) xa=x scale * pow(sin(i),3) * 15; ya=y scale * (15*cos(i) - 5*cos(2*i) - 2*cos(3*i) - cos(4*i)); line safe(xa+xx,ya+yy); pen up();

//Box1 void rectangle(float xx,float yy,float dx,float dy,float angle)

{ float six,csx,siy,csy; dx/=2; dy/=2; six = sin(angle/180*3 14) * dx; csx = cos(angle/180*3 14) * dx; siy = sin(angle/180*3 14) * dy; csy = cos(angle/180*3 14) * dy; pen up(); line safe(csx - siy + xx,six + csy + yy); pen down(); line safe(xx - csx - siy,csy - six + yy); line safe(xx - csx + siy,yy - csy - six); line safe(csx + siy + xx,six - csy + yy); line safe(csx - siy + xx,six + csy + yy); pen up();

//box2 void box(float xx,float yy,float dx,float dy)

{ pen up(); line safe(xx , yy); pen down(); delay(TPD); line safe(xx + dx, yy); delay(TPD); line safe(xx + dx, yy+ dy); delay(TPD); line safe(xx , yy + dy); delay(TPD); line safe(xx , yy); pen up();

// circle void circle(float xx,float yy,float radius x,float radius y) float rx,ry; float st= 3 14159 / 90; // circle division accuracy pen up(); line(xx+radius x,yy); pen down(); for(float i=0;i<6.28318;i+=st) rx = cos(i) * radius x; ry = sin(i) * radius y; line(xx+rx,yy+ry); pen up();

//circular arc void arc(float xx,float yy,float radius,float sangle,float eangle) float rx,ry,i; sangle+=360; eangle+=360; sangle=sangle / 180 * PI; //convert to radians 360 degrees = 2Π eangle=eangle / 180 * PI; float st= 3 14159 / 360; // circle division accuracy pen up(); line(xx+cos(sangle)*radius,yy+sin(sangle)*radius); pen down(); if (sangle<eangle) { for(i=sangle;i<eangle;i+=st) rx = cos(i) * radius; ry = sin(i) * radius; line(xx+rx,yy+ry);

} else { for(i=sangle;i>eangle;i-=st) rx = cos(i) * radius; ry = sin(i) * radius; line(xx+rx,yy+ry);

} pen up(); } //star { void star(float xx,float yy,float radius r,int corner) void setup() {

// put your setup code here, to run once: Serial.begin(BAUD); m1 connectToPins(7,8,9,10); //M1 L stepper motor in1~4 ports corresponding to UNO 7 8 9 10 m2 connectToPins(2,3,5,6); //M2 R stepper motor in1~4 ports corresponds to UNO 2 3 5 6 m1 setSpeedInStepsPerSecond(10000); m1 setAccelerationInStepsPerSecondPerSecond(100000); m2 setSpeedInStepsPerSecond(10000); m2 setAccelerationInStepsPerSecondPerSecond(100000);

// lift the pen servo pen attach(A0); ps=PEN UP ANGLE; pen write(ps);

//set the current pen position to 0, 0 teleport(0, 0); pen up(); Serial println("Test OK!"); } void loop() {

//Demo program will draw some simple graphics delay, please debug the parameters, the A4 or larger paper, centered on the pen holder before turning on the machine demo3();

//demo2(); //remove the top //also demonstrate another code moveto(0,0); void demo2() { int rd=0; float sa,ea; rd=random(10); sa=random(0,360); do { if (rd >95) rd=100; else rd+=random(8,15); ea=random(5,15); int z=map(random(0,2),0,1,-1,1); ea=sa+ea*z;

Serial println("sa: "+String(sa)+" ea: "+String(ea)); pen down(); line(cos(sa/180*PI)*rd,sin(sa/180*PI)*rd); arc(0,0,rd,sa,ea); sa=ea;

} while (rd<100); } void demo1() { pen up(); box(-45,0,90,90); moveto(-15,0); pen down(); line(-15,90); pen up(); moveto(15,90); pen down(); line(15,0); pen up(); moveto(-45,30); pen down(); line(45,30); pen up(); moveto(45,60); pen down(); line(-45,60); pen up(); box(-42 5,62 5,25,25); circle(0,75,12.5,12.5); rectangle(30,75,17 7,17 7,45); rectangle(-30,45,17 7,17 7,45); box(-12 5,32 5,25,25); circle(30,45,12 5,12 5); circle(-30,15,12.5,12.5); rectangle(0,15,17 7,17 7,45); box(17 5,2 5,25,25);

// heart curve Parameters (x, y position, x magnification, y magnification) heart curve(-45,-45,2,2);

//butterfly line Parameters(x,y position, the larger the circle the more complex, x magnification, y magnification) butterfly curve(45,-55,3,12,12);

} void demo3(){ while(1){ pen up(); pen down();

This article is from: