CNC Sewing Machine – Part 2
I’ve been encouraged to post a little more about the sewing machine, so here is an update on progress. I’ve modified the Arduino code to accept direct input from a computer, so it is possible to run custom patterns of arbitrary length. I’ve written a quick python script that can take an image and convert it into a stitch pattern.
The communication system for the computer/Arduino interface is very basic:
- Computer waits until it receives the “X” character from the Arduino, then sends 2 bytes of information. Byte 1 is the needle position, and is a range between 0 and 64. Byte 2 is the feed direction and position, also ranged between 0 and 64 (32 is no movement – the material does not advance)
- The Arduino sets the servos into the correct positions when the needle is up, and then requests another 2 bytes by sending “X”
I intend to modify the code so that you can make use of the dials on the front of the machine. For example – sending the value 200 to the Arduino will tell the Arduino to read the value of the zigzag dial, and sending 210 will use the value of the feed dial. This way, it will be possible to set a general computer pattern and modify it in real-time at the machine.
The arduino will also return the value of the dials, so that you will be able to switch between patterns from a list stored in the PC. This will make it easier to embroider letters and small symbols automatically.
I’ve covered up the electronics now that the paint has finally arrived, and I will be giving the body of the machine some TLC to cover up the rust stains and paint chips. Mechanically, the machine is in much better condition than it was. I have cleaned and oiled the mechanism, which has reduced the noise level considerably. I will raise the machine onto cork feet to help reduce noise.
I replaced the wire connecting the feed servo to the feed arm, because the twisted copper wire was too flexible. The replacement bar is made from steel with some nails brazed onto it to hook the servo and feed arm. The result is a much more accurate feed control.
The code I’m working on at the moment is here:
-
-
#include
-
// needlesensor = 11, zigzag servo = 10, feed servo = 9
-
// the lut is a lookup table to correct the polar / linear offset from the machinery
-
-
// these are the patterns, numbered 1-10. End of pattern is indicated by stitch value of 255 (valid number range for stitches is 64)
-
const byte pattern[11][64] =
-
{
-
{}, // empty to soak up the zero index
-
{0, 10, 21, 32, 42, 53, 64, 53, 42, 32, 21, 10, 255},
-
{10, 32, 53, 32, 255},
-
{0, 0, 0, 0, 0, 32, 64, 64, 64, 64, 64, 255},
-
{10, 42, 21, 42, 64, 53, 32, 42, 32, 21, 32, 42, 64, 21, 32, 53, 21, 53, 32, 32, 64, 21, 10, 10, 42, 53, 32, 53, 10, 255},
-
{32, 42, 21, 53, 21, 53, 10, 64, 10, 64, 10, 64, 21, 53, 21, 53, 32, 42, 42, 32, 255},
-
{0, 10, 53, 64, 53, 10, 255},
-
{0, 21, 32, 42, 64, 42, 32, 21, 255},
-
{32, 37, 42, 48, 52, 56, 59, 62, 63, 64, 63, 62, 59, 56, 52, 48, 42, 37, 32, 26, 21, 16, 11, 7, 4, 1, 0, 0, 0, 1, 4, 7, 11, 16, 21, 26, 255},
-
{0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 64, 32, 64, 32, 64, 32, 64, 32, 64, 32, 255},
-
{0, 63, 2, 61, 4, 59, 6, 57, 8, 55, 10, 53, 12, 51, 15, 48, 17, 46, 19, 44, 21, 42, 23, 40, 25, 38, 27, 36, 29, 34, 29, 34, 27, 36, 25, 38, 23,
-
40, 21, 42, 19, 44, 17, 46, 15, 48, 12, 51, 10, 53, 8, 55, 6, 57, 4, 59, 2, 61, 0, 63, 255}
-
};
-
byte lut[65] = {
-
0, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 13, 14, 15, 16, 17, 18, 18, 19, 20, 21, 22, 22, 23, 24, 25, 25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32,
-
33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 42, 44, 45, 47, 48, 50, 52, 53, 55, 57, 59, 60, 62, 64};
-
-
// set pin numbers:
-
const byte buttonPin = 11; // the number of the pushbutton pin
-
const byte modePin = 6; // zigzag when low
-
const byte codePin = 7; // direct serial mode when high
-
const byte zigzagpotpin = 0; // analog pin used to connect the potentiometer
-
const byte feedpotpin = 1; // analog pin used to connect the potentiometer
-
const byte ledPin = 13;
-
-
// these are the settings perculiar to the machine
-
// Change these for different machines
-
const byte feedmin = 50;
-
const byte feedmax = 105;
-
const byte zigzagmin = 105;
-
const byte zigzagmax = 169;
-
const byte zigzagc = 132;
-
-
// create servo objects
-
Servo feed;
-
Servo zigzag;
-
-
int feedval; // variable to read the value from the feed potentiometer
-
int zigzagval; // variable to read the value from the zigzag potentiometer
-
boolean needlepos = LOW;
-
boolean pulse = HIGH; // general heartbeat for zigzag function
-
-
// The programming variables
-
boolean mode; // the mode select pin value
-
boolean code; // the computer code select pin value
-
byte pos; // the position within the pattern
-
byte prog; // the active pattern number, set by zigzag pot position.
-
byte oldprog; // the program on last iteration. used to reset pos to zero if program changes.
-
byte stitchpos; // the position of the stitch, adjusted for machine using map
-
byte prog_feed; // byte to store serial input.
-
byte prog_width;
-
-
void do_program(){
-
needlepos = digitalRead(buttonPin); // get the needle position
-
feedval = analogRead(feedpotpin); // reads the value of the feed pot
-
feedval = map(feedval, 0, 1023, feedmin, feedmax); // scale it to use it with the servo
-
-
zigzagval = analogRead(zigzagpotpin); // get the zigzag pot position
-
prog = map(zigzagval, 0, 1023, 1, 10); // convert to 1-10 for program select
-
-
// check to see if the pattern has changed and look for the 999 end symbol in the pattern
-
if (prog != oldprog || pattern[prog][pos] == 255){
-
pos = 0;
-
}
-
-
if (needlepos == HIGH) {
-
digitalWrite(ledPin, HIGH);
-
// set the stitch position
-
stitchpos = map(lut[pattern[prog][pos]], 0, 64, zigzagmin, zigzagmax); // scale it to use it with the servo
-
Serial.println(int(pattern[prog][pos])); Serial.println(int(lut[pattern[prog][pos]])); Serial.println(int(stitchpos));
-
zigzag.write(stitchpos);
-
-
// move the feed if necessary
-
// get the feed value
-
feedval = analogRead(feedpotpin); // reads the value of the potentiometer
-
feedval = map(feedval, 0, 1023, feedmin, feedmax); // scale it to use it with the servo
-
feed.write(feedval); // sets the servo position according to the scaled value
-
-
// wait for needle to move down
-
while (needlepos == HIGH) { needlepos = digitalRead(buttonPin); }
-
pos = pos++; // increment the position
-
digitalWrite(ledPin, LOW);
-
}
-
oldprog = prog;
-
}
-
-
void do_zigzag(){
-
needlepos = digitalRead(buttonPin); // get the needle position
-
-
if (needlepos == HIGH) {
-
// get the zigzag value
-
zigzagval = analogRead(zigzagpotpin); // reads the value of the potentiometer
-
digitalWrite(ledPin, HIGH);
-
-
// decide whether to zig or zag
-
if (pulse == HIGH){
-
zigzagval = map(zigzagval, 0, 1023, zigzagmin, zigzagc); // scale it to use it with the servo
-
zigzag.write(zigzagval);
-
pulse = LOW;
-
} else if (pulse == LOW) {
-
zigzagval = map(zigzagval, 0, 1023, zigzagmax, zigzagc); // scale it to use it with the servo
-
zigzag.write(zigzagval);
-
pulse = HIGH;
-
}
-
// wait for needle to move down
-
while (needlepos == HIGH) { needlepos = digitalRead(buttonPin); } // get the needle position
-
}
-
-
if (needlepos == LOW) {
-
// get the feed value
-
feedval = analogRead(feedpotpin); // reads the value of the potentiometer
-
feedval = map(feedval, 0, 1023, feedmin, feedmax); // scale it to use it with the servo
-
-
digitalWrite(ledPin, LOW);
-
feed.write(feedval); // sets the servo position according to the scaled value
-
Serial.println(feedval,DEC);
-
-
// wait for needle to move up
-
while (needlepos == LOW) { needlepos = digitalRead(buttonPin); }
-
}
-
}
-
-
void setup()
-
{
-
// initialize serial communication:
-
Serial.begin(9600);
-
-
// attach the servos
-
feed.attach(9);
-
zigzag.attach(10);
-
-
// move the servos into place
-
feed.write(feedmin);
-
zigzag.write(zigzagc);
-
-
// setup the input for needle sensor
-
pinMode(buttonPin, INPUT);
-
pinMode(modePin, INPUT);
-
-
}
-
-
void loop()
-
{
-
// choose mode
-
mode = digitalRead(modePin);
-
code = digitalRead(codePin);
-
if (code == HIGH){
-
do_code();
-
}else{
-
if (mode == LOW){
-
do_zigzag();
-
} else {
-
do_program();
-
}
-
}
-
}
-
-
void do_code(){
-
// send X to get next chars
-
// send E for error
-
-
// 0-64 is position
-
// 0-64 is direction
-
// get two bytes
-
// 1st byte is stitch position, 2nd is feed
-
-
needlepos = digitalRead(buttonPin); // get the needle position
-
-
// send ready and wait for a value
-
Serial.print("X");
-
while (Serial.available() < 2)
-
{// wait until we have 2 char
-
// exit if mode changes
-
code = digitalRead(codePin);
-
if (code == LOW){
-
return;
-
}
-
}
-
-
// read the incoming character
-
prog_width = Serial.read();
-
prog_feed = Serial.read();
-
-
// set the foot, then position the head when needle is up
-
-
needlepos = digitalRead(buttonPin); // get the needle position
-
if (needlepos = HIGH){
-
digitalWrite(ledPin, HIGH);
-
stitchpos = map(lut[prog_width], 0, 64, zigzagmin, zigzagmax); // scale stitch width to use it with the servo
-
feedval = map(prog_feed, 0, 64, feedmin, feedmax); // scale feed value to use it with the servo
-
-
feed.write(feedval);
-
zigzag.write(stitchpos);
-
while (needlepos == HIGH) { needlepos = digitalRead(buttonPin); }
-
}
-
-
digitalWrite(ledPin, LOW);
-
while (needlepos == LOW) { needlepos = digitalRead(buttonPin); }
-
-
}




Hi,
.. I really like the way you have used the Arduino:)…
Very interesting project
I also did some work on CNC embroidery Machine.. I made a software that converts DST file to Gcode.. and you can then get beautiful embroidery work with CNC converted sewing machine.
http://www.my-woodcarving.blogspot.com
My software is free for all