I want to customize bends with different designs
I made my machine based on this website here
3D wire bending machine
The machine I made was exactly as it is on the website
I made 3 designs 100%
star, square, triangle
Now I need to customize different designs
I want your help to exchange information
with windscreen designs or from CAD
DaveX
March 23, 2025, 3:06pm
2
The code looks like there's a manual mode, so you need only translate your designs into the odd machine control dialect.
/*
Arduino 3D Wire Bending Machine
by Dejan Nedelkovski
www.HowToMechatronics.com
Library - AccelStepper by Mike McCauley:
http://www.airspayce.com/mikem/arduino/AccelStepper/index.html
*/
#include <AccelStepper.h>
#include <Servo.h>
#define limitSwitch 11
// Define the stepper motors and the pins the will use
AccelStepper feederStepper(1, 5, 6); // (Type:driver, STEP, DIR)
AccelStepper zAxisStepper(1, 7, 8);
AccelStepper benderStepper(1, 9, 10);
Servo servo01;
String dataIn = "";
String manualStatus = "";
int count = 0;
int dist;
void setup() {
Serial.begin(9600);
pinMode(limitSwitch, INPUT_PULLUP);
servo01.attach(2);
servo01.write(40); // Initial position, bending pin up
// Stepper motors max speed
feederStepper.setMaxSpeed(2000);
zAxisStepper.setMaxSpeed(2000);
benderStepper.setMaxSpeed(2000);
// Homing
while (digitalRead(limitSwitch) != 0) {
benderStepper.setSpeed(1200);
benderStepper.runSpeed();
benderStepper.setCurrentPosition(0); // When limit switch pressed set position to 0 steps
}
delay(40);
// Move 1400 steps from the limit switch to starting position
while (benderStepper.currentPosition() != -1400) {
benderStepper.setSpeed(-1200); // if negative rotates anti-clockwise
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
}
void loop() {
String mode = Serial.readString();
if (mode.startsWith("manual")) {
manual();
}
if (mode.startsWith("star")) {
star();
}
if (mode.startsWith("cube")) {
cube();
}
if (mode.startsWith("stand")) {
stand();
}
}
void star() {
while (count != 5) {
int feed = 38; // mm
int feedDistance = feed * 48; // 48- constats that map the mm value to number of steps the stepper show move
while (feederStepper.currentPosition() != feedDistance) { // run until it reaches the distance value
feederStepper.setSpeed(1200);
feederStepper.run();
}
feederStepper.setCurrentPosition(0); // reset the current position to 0
servo01.write(40); // Set the bender pin up
delay(200);
int angleConst = 18; // angle constant
// Bend the wire 52 degrees
while (benderStepper.currentPosition() != -52 * angleConst) {
benderStepper.setSpeed(-700);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
// Go back 52 degrees to initial position
while (benderStepper.currentPosition() != 52 * angleConst) {
benderStepper.setSpeed(1200);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
// Feed the same distance again
while (feederStepper.currentPosition() != feedDistance) {
feederStepper.setSpeed(1200);
feederStepper.run();
}
feederStepper.setCurrentPosition(0);
delay(100);
servo01.write(130); // Set the bender pin down
delay(200);
// Set bender to new initial position, for bending in the other direction
while (benderStepper.currentPosition() != -42 * angleConst) {
benderStepper.setSpeed(-1200);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(200);
servo01.write(40); // Bender pin up
delay(200);
while (benderStepper.currentPosition() != 105 * angleConst) {
benderStepper.setSpeed(700);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(50);
while (benderStepper.currentPosition() != -63 * angleConst) {
benderStepper.setSpeed(-1200);
benderStepper.run();
}
delay(100);
servo01.write(130);
benderStepper.setCurrentPosition(0);
count++;
}
}
void cube() {
int feed = 40; // mm
int feedDistance = feed * 48;
int angleConst = 16;
// Step 1
while (count != 3) {
while (feederStepper.currentPosition() != feedDistance) {
feederStepper.setSpeed(1200);
feederStepper.run();
}
feederStepper.setCurrentPosition(0);
delay(100);
while (benderStepper.currentPosition() != -90 * angleConst) {
benderStepper.setSpeed(-700);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
while (benderStepper.currentPosition() != 90 * angleConst) {
benderStepper.setSpeed(1200);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
count++;
}
count = 0;
// Step 2
while (zAxisStepper.currentPosition() != 88 * angleConst) {
zAxisStepper.setSpeed(500);
zAxisStepper.run();
}
zAxisStepper.setCurrentPosition(0);
delay(100);
//Step 3
while (count != 2) {
while (feederStepper.currentPosition() != feedDistance) {
feederStepper.setSpeed(1200);
feederStepper.run();
}
feederStepper.setCurrentPosition(0);
delay(100);
while (benderStepper.currentPosition() != -90 * angleConst) {
benderStepper.setSpeed(-700);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
while (benderStepper.currentPosition() != 90 * angleConst) {
benderStepper.setSpeed(1200);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
count++;
}
count = 0;
// Step 4
while (zAxisStepper.currentPosition() != 85 * angleConst) {
zAxisStepper.setSpeed(500);
zAxisStepper.run();
}
zAxisStepper.setCurrentPosition(0);
delay(100);
// Step 5
servo01.write(130);
delay(200);
while (benderStepper.currentPosition() != -42 * angleConst) {
benderStepper.setSpeed(-1200);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
while (count != 3) {
delay(100);
servo01.write(40);
delay(200);
// Step 6
while (feederStepper.currentPosition() != feedDistance) {
feederStepper.setSpeed(1200);
feederStepper.run();
}
feederStepper.setCurrentPosition(0);
delay(100);
while (benderStepper.currentPosition() != 90 * angleConst) {
benderStepper.setSpeed(700);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
while (benderStepper.currentPosition() != -90 * angleConst) {
benderStepper.setSpeed(-1200);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
count++;
}
count = 0;
}
void stand() {
int feed = 20; // mm
int feedDistance = feed * 48;
int angleConst = 16;
// Step 1
while (feederStepper.currentPosition() != feedDistance) {
feederStepper.setSpeed(1200);
feederStepper.run();
}
feederStepper.setCurrentPosition(0);
delay(100);
while (benderStepper.currentPosition() != -90 * angleConst) {
benderStepper.setSpeed(-700);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
while (benderStepper.currentPosition() != 90 * angleConst) {
benderStepper.setSpeed(1200);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
// Step 2
while (feederStepper.currentPosition() != feedDistance) {
feederStepper.setSpeed(1200);
feederStepper.run();
}
feederStepper.setCurrentPosition(0);
delay(100);
while (benderStepper.currentPosition() != -70 * angleConst) {
benderStepper.setSpeed(-700);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
while (benderStepper.currentPosition() != 70 * angleConst) {
benderStepper.setSpeed(1200);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
// Step 3
feed = 80; // mm
feedDistance = feed * 48;
while (feederStepper.currentPosition() != feedDistance) {
feederStepper.setSpeed(1200);
feederStepper.run();
}
feederStepper.setCurrentPosition(0);
delay(100);
// Step 4
servo01.write(130);
delay(200);
while (benderStepper.currentPosition() != -42 * angleConst) {
benderStepper.setSpeed(-1200);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
servo01.write(40);
delay(200);
while (benderStepper.currentPosition() != 108 * angleConst) {
benderStepper.setSpeed(700);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
while (benderStepper.currentPosition() != -66 * angleConst) {
benderStepper.setSpeed(-1200);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
//Step 5
servo01.write(130);
delay(200);
// Step 6
feed = 80; // mm
feedDistance = feed * 48;
while (feederStepper.currentPosition() != feedDistance) {
feederStepper.setSpeed(1200);
feederStepper.run();
}
feederStepper.setCurrentPosition(0);
servo01.write(40);
delay(200);
// Step 7
while (zAxisStepper.currentPosition() != -90 * angleConst) {
zAxisStepper.setSpeed(-500);
zAxisStepper.run();
}
zAxisStepper.setCurrentPosition(0);
delay(100);
// Step 8
while (benderStepper.currentPosition() != -90 * angleConst) {
benderStepper.setSpeed(-700);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
while (benderStepper.currentPosition() != 90 * angleConst) {
benderStepper.setSpeed(1200);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
// Step 6
feed = 45; // mm
feedDistance = feed * 48;
while (feederStepper.currentPosition() != feedDistance) {
feederStepper.setSpeed(1200);
feederStepper.run();
}
feederStepper.setCurrentPosition(0);
// Step 10
while (benderStepper.currentPosition() != -90 * angleConst) {
benderStepper.setSpeed(-700);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
while (benderStepper.currentPosition() != 48 * angleConst) {
benderStepper.setSpeed(1200);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
// Step 11
while (zAxisStepper.currentPosition() != 90 * angleConst) {
zAxisStepper.setSpeed(500);
zAxisStepper.run();
}
zAxisStepper.setCurrentPosition(0);
delay(100);
feed = 80; // mm
feedDistance = feed * 48;
while (feederStepper.currentPosition() != feedDistance) {
feederStepper.setSpeed(1200);
feederStepper.run();
}
feederStepper.setCurrentPosition(0);
// Step 12
while (benderStepper.currentPosition() != 110 * angleConst) {
benderStepper.setSpeed(700);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
while (benderStepper.currentPosition() != -68 * angleConst) {
benderStepper.setSpeed(-1200);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
//Step 13
servo01.write(130);
delay(200);
feed = 80; // mm
feedDistance = feed * 48;
while (feederStepper.currentPosition() != feedDistance) {
feederStepper.setSpeed(1200);
feederStepper.run();
}
feederStepper.setCurrentPosition(0);
servo01.write(40);
delay(200);
// Step 14
while (benderStepper.currentPosition() != -70 * angleConst) {
benderStepper.setSpeed(-700);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
while (benderStepper.currentPosition() != 70 * angleConst) {
benderStepper.setSpeed(1200);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
//Step 15
feed = 25; // mm
feedDistance = feed * 48;
while (feederStepper.currentPosition() != feedDistance) {
feederStepper.setSpeed(1200);
feederStepper.run();
}
feederStepper.setCurrentPosition(0);
delay(100);
// Step 16
while (benderStepper.currentPosition() != -90 * angleConst) {
benderStepper.setSpeed(-700);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
while (benderStepper.currentPosition() != 90 * angleConst) {
benderStepper.setSpeed(1200);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
// Step 17
while (feederStepper.currentPosition() != feedDistance) {
feederStepper.setSpeed(1200);
feederStepper.run();
}
feederStepper.setCurrentPosition(0);
}
void manual() {
int sign;
String dataInS;
int angle;
int angleConst;
Serial.println(" // MANUAL MODE //");
while (!dataIn.startsWith("end")) {
servo01.write(130);
delay(200);
dataIn = Serial.readString();
if (dataIn.startsWith("f")) {
dataInS = dataIn.substring(1, dataIn.length()); // reads the feed value
dist = dataInS.toInt();
Serial.print("Feed ");
Serial.print(dist);
Serial.println("mm wire.");
dist = dist * 48;
while (feederStepper.currentPosition() != dist) {
feederStepper.setSpeed(1200);
feederStepper.run();
}
feederStepper.setCurrentPosition(0);
delay(100);
}
if (dataIn.startsWith("b")) {
if (dataIn.charAt(1) == '-') {
dataInS = dataIn.substring(2, dataIn.length()); ///reads the angle value
angle = dataInS.toInt();
Serial.print("Bend -");
Serial.print(angle);
Serial.println(" degrees.");
angleConst = 16;
// Set "negative" bending initial position
while (benderStepper.currentPosition() != -43 * angleConst) {
benderStepper.setSpeed(-1200);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
servo01.write(40);
delay(200);
// Bend the wire
while (benderStepper.currentPosition() != angle * angleConst) {
benderStepper.setSpeed(700);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
while (benderStepper.currentPosition() != (-1) * angle * angleConst) {
benderStepper.setSpeed(-1200);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
servo01.write(130);
delay(200);
// Get back to original "positive" bending initial poistion
while (benderStepper.currentPosition() != 43 * angleConst) {
benderStepper.setSpeed(1200);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
}
else {
dataInS = dataIn.substring(1, dataIn.length());
angle = dataInS.toInt();
Serial.print("Bend ");
Serial.print(angle);
Serial.println(" degrees.");
angleConst = 16;
servo01.write(40);
delay(200);
while (benderStepper.currentPosition() != (-1) *angle * angleConst) {
benderStepper.setSpeed(-700);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
while (benderStepper.currentPosition() != angle * angleConst) {
benderStepper.setSpeed(1200);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
}
dataInS = dataIn.substring(2, dataIn.length());
angle = dataInS.toInt();
angleConst = 16;
while (benderStepper.currentPosition() != sign * angle * angleConst) {
benderStepper.setSpeed(-700);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
while (benderStepper.currentPosition() != sign * angle * angleConst) {
benderStepper.setSpeed(1200);
benderStepper.run();
}
benderStepper.setCurrentPosition(0);
delay(100);
}
// Z-Axis Control
if (dataIn.startsWith("z")) {
if (dataIn.charAt(1) == '-') {
dataInS = dataIn.substring(2, dataIn.length());
angle = dataInS.toInt();
Serial.print("Move Z-Axis -");
Serial.print(angle);
Serial.println(" degrees.");
angleConst = 16;
while (zAxisStepper.currentPosition() != angle * angleConst) {
zAxisStepper.setSpeed(500);
zAxisStepper.run();
}
zAxisStepper.setCurrentPosition(0);
delay(100);
}
else {
dataInS = dataIn.substring(1, dataIn.length());
angle = dataInS.toInt();
Serial.print("Move Z-Axis ");
Serial.print(angle);
Serial.println(" degrees.");
angleConst = 16;
while (zAxisStepper.currentPosition() != (-1) *angle * angleConst) {
zAxisStepper.setSpeed(-500);
zAxisStepper.run();
}
zAxisStepper.setCurrentPosition(0);
delay(100);
}
}
manualStatus = dataIn;
}
}
That is a cool machine, but it looks like the author never wrote a general purpose control interface, so every design has to be hard coded.
To exchange and utilize design information requires a set of standard definitions that everyone will agree upon and use.
What have you come up with so far?
I discovered a way to make a drawing in AUTO CAD, send the coordinates to Excel and copy the calculations from Excel to Arduino and the machine starts to fold.
This is a way that another friend from Russia is doing,
but he can only do it in his program and his program didn't turn out very well.
THAT'S WHY I WAS INTERESTED IN DOING IT IN THIS PROGRAM FROM THE SITE THAT I DOWNLOADED, I FOUND IT MUCH MORE PERFECT,
BUT I DIDN'T SEE A WAY TO PUT THE EXECUTABLE FILE THAT I MADE
So my friend actually has the manual function
where I type star and the machine folds the star
if I type cube it draws perfectly but only 3 drawings that already have the coordinates in the program
but I want to make other personalized ones like a friend from Russia, he makes a drawing in AUTO CAD, copies the coordinates to Excel, Excel does the calculation
takes the calculation from Excel and pastes it into Arduino and the machine starts folding
Serial.println(" Guram 091 mm;\t"); Gurni(91); Serial.println("Rb.1. LEVO savija 41,3 stepeni;\t"); Savi(153,2,1,2);
Serial.println(" Guram 097 mm;\t"); Gurni(97); Serial.println("Rb.2. LEVO savija 75,2 stepeni;\t"); Savi(231,2,2,2);
Serial.println(" Guram 095 mm;\t"); Gurni(95); Serial.println("Rb.3. LEVO savija 63,4 stepeni;\t"); Savi(206,2,2,2);
Serial.println(" Guram 096 mm;\t"); Gurni(96); Serial.println("Rb.4. LEVO savija 40,8 stepeni;\t"); Savi(152,2,2,1);
Serial.println(" Guram 097 mm;\t"); Gurni(97);
This one I sent is a drawing ready to paste on the Arduino
executable design
Start by writing a general purpose control interface that carries out all the machine functions.
Example machine and human readable commands might be something like these (numbers can be positive or negative, absolute or relative)
extrude wire 15 mm
rotateZ 30 degrees
incrementZ 15 degrees
bend 45 degrees
incrementbend 1 degree
check limit switch 1
friend, if you can talk to me on whatsapp or
telegram or viber, I'll send you my contact
Mod edit: Personal details removed.
If you want to give someone your personal details please do so in a private message.
Thank you
xfpd
March 23, 2025, 11:38pm
8
I find the use of flat text arrays an easy-to-read AND easy-to-edit means to convey information to a human or a machine, much like multi-position punch tape (or punch cards).
I created a functional, generic "punch tape reader" (single-flat-text-array) that turns digital pins ON and OFF, depending on the text-based contents of a "tape" which is a single-dimension array of dots and stars that can control the on/off sequence of all the DIO pins of an Uno or Nano. The speed of the "tape" is set in a global variable. The resolution is determined by the length of the "tape" (number of characters in a row).
Here is a sample of a "tape" that currently turns LEDs ON ("*") or OFF ("."). Each column is read, then each element in the column is translated to an action (ON or OFF).
char scroll01[] = {
//2345....1.........2.........3.........4.........5 // column count
"*...........................*....................." // single-dimension array...
".......*.............*.............*.............*" // ... no open/close braces
"..............*...........................*......." // ... no delimiting commas
"*......*......*......*......*......*......*......*" // .... no closing semi-colons
};
In terms of the wire-bender... imagine; each star of line 4 means "feed wire 10mm" and every start on line 3 means "bend left" and every star on line 2 means "bend right" and every star on line 1 means "cut wire". The functions waiting to bend and cut could be triggered by the "stars", You could also add text characters to "*" and "." to mean adjust angle, or adjust speed.
The "tape" is extensible in length to the limit of memory. The "tape" can be as few as 1 DIO pin, to as many DIO pins available (Nano 19, Mega 54).
This simulation has some features: randomness, looping, "tape" selection, various "tape" lengths. These "tapes" are only three "rows" tall, but can be increased to the number of DIO pins needed.
Run IoT and embedded projects in your browser: ESP32, STM32, Arduino, Pi Pico, and more. No installation required!
xfpd
March 23, 2025, 11:59pm
10
jairo435:
I understand
That is good. You can add, read and edit the "tapes" to your needs.
jairo435:
email or whatsapp
No.
jairo435:
(post deleted by author)
: (
Friend, I saw that you have good knowledge,
if I pay you in cash for your working time, you can help me ?
xfpd
March 25, 2025, 1:13am
12
If you want to pay someone, you must have your topic moved to Jobs and Paid Consultancy - Arduino Forum
Otherwise, it will be solved here.
Ask the moderator to move your post to the Jobs and Paid Consultancy forum section.
@jairo435 ,
I am a moderator, do you wish to continue here with free help or do you want this moved to the paid category of the forum?
ledsyn
March 25, 2025, 12:09pm
17
We can clearly see that you Caps lock works, please don't repeat the test.
DaveX
March 25, 2025, 12:50pm
18
That's not using your "manual" function. The manual function in the code above makes it so you can avoid re-programming the Arduino. You can instead tell it to go into "manual" mode:
... and then on the computer side send the manual commands (e.g. f123 b45 z67) to the waiting arduino.
Perhaps someone good at Excel could write the the excel macro to send the commands directly from Excel.
Boy, you creative guy managed to make the turtle draw the star of the machine lol
xfpd
March 26, 2025, 3:17am
22
You can simplify the code you have to do the same as Turtle. I started re-working my "sequencer" to work with your "extrude, bend, increase angle, rotate, extrude, bend, ..." but thought that "Turtle Graphics" was a better example. Using the sequencer you could assign a line to a function, and every time the "line" had a "value" the function would receive that value and execute that number of actions...
// VALID INPUTS
int i = 1, v = 5, x = 10, l = 50, c = 100, m = 1000 // additive Roman number system
const char sequence[] = {
// 12345....1.........2.........3.........4.........5
/* FEED */ "iv................................................"
/* ROTZ */ "...xxx............................................"
/* INCZ */ "........xv........................................"
/* DECZ */ ".................................................."
/* BEND */ "...........xv....................................."
/* INCB */ "..............i..................................."
/* DECB */ ".................................................."
// 12345....1.........2.........3.........4.........5
};
For example, row 1 is the feed line... and the value is "i" so you would feed "1." The next value in row1 is "v" so the "feed" function would feed 5 more times... The a pause "." Then "rotate z" gets the value of "xxx" = 30, followed by the increase of Z rotation by 15, then the bend will take the value of 15 (increments of 1 degree), ending with an increase of bending angle by 1.
I believe a simpler sketch and method can be written to allow simple, flat, text arrays to represent all the bends, and not the intricate code that was written and shown in the video.