Pages: [1] 2 3 ... 10   Go Down
Author Topic: 28BYJ-48 5-Volt Stepper  (Read 77532 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 3
Posts: 52
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

FYI - below is some Arduino code that demonstrates bidirectional operation of a 28BYJ-48 5-Volt stepper motor. It does not use the Arduino library partly because I wanted to get a bit more hands-on with the stepper to learn its operation and partly because the library isn't designed for this type of stepper and the pin assignments need to flipped around to work. Plus, I don't think that the library correctly addresses the eight codes required for this stepper and, instead, uses only four codes. Anyway, this code works well for a functionality demo. The code is based on some general stepper code that I found on the web (I don't recall where) and modified for the  28BYJ-48 stepper. I have also attached a photo of the stepper and interface board that I am using - <$5 for both on eBay. I have also attached a schematic for the ULN2003 Driver Board.

Code:
// This Arduino example demonstrates bidirectional operation of a
// 28BYJ-48, which is readily available on eBay, using a ULN2003
// interface board to drive the stepper. The 28BYJ-48 motor is a 4-
// phase, 8-beat motor, geared down by a factor of 68. One bipolar
// winding is on motor pins 1 & 3 and the other on motor pins 2 & 4.
// Refer to the manufacturer's documentation of  Changzhou Fulling
// Motor Co., Ltd., among others.  The step angle is 5.625/64 and the
// operating Frequency is 100pps. Current draw is 92mA.  In this
// example, the speed and direction of the stepper motor is determined
// by adjusting a 1k-ohm potentiometer connected to Arduino pin A2.
// When the potentiometer is rotated fully counterclockwise, the motor
// will rotate at full counterclockwise speed. As the potentiometer is
// rotated clockwise, the motor will continue to slow down until is
// reaches its minimum speed at the the potentiometer's midpoint value .
// Once the potentiometer crosses its midpoint, the motor will reverse
// direction. As the potentiometer is rotated further clockwise, the speed  
// of the motor will increase until it reaches its full clockwise rotation
// speed when the potentiometer has been rotated fully clockwise.
////////////////////////////////////////////////

//declare variables for the motor pins
int motorPin1 = 8; // Blue   - 28BYJ48 pin 1
int motorPin2 = 9; // Pink   - 28BYJ48 pin 2
int motorPin3 = 10; // Yellow - 28BYJ48 pin 3
int motorPin4 = 11; // Orange - 28BYJ48 pin 4
                        // Red    - 28BYJ48 pin 5 (VCC)

int motorSpeed = 0;     //variable to set stepper speed
int potPin = 2; //potentiometer connected to A2
int potValue = 0; //variable to read A0 input


//////////////////////////////////////////////////////////////////////////////
void setup() {
  //declare the motor pins as outputs
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
  pinMode(motorPin4, OUTPUT);
  Serial.begin(9600);
}

//////////////////////////////////////////////////////////////////////////////
void loop(){

  potValue = analogRead(potPin);     // read the value of the potentiometer
  Serial.println(potValue);          // View full range from 0 - 1024 in Serial Monitor
  if (potValue < 535){               // if potentiometer reads 0 to 535 do this
    motorSpeed = (potValue/15 + 5);  //scale potValue to be useful for motor
    clockwise();                     //go to the ccw rotation function
  }
  else {                             //value of the potentiometer is 512 - 1024
    motorSpeed = ((1024-potValue)/15 + 5); //scale potValue for motor speed
    counterclockwise(); //go the the cw rotation function
  }
}

//////////////////////////////////////////////////////////////////////////////
//set pins to ULN2003 high in sequence from 1 to 4
//delay "motorSpeed" between each pin setting (to determine speed)

void counterclockwise (){
  // 1
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delay(motorSpeed);
  // 2
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delay (motorSpeed);
  // 3
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delay(motorSpeed);
  // 4
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(motorSpeed);
  // 5
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(motorSpeed);
  // 6
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, HIGH);
  delay (motorSpeed);
  // 7
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(motorSpeed);
  // 8
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(motorSpeed);
}

//////////////////////////////////////////////////////////////////////////////
//set pins to ULN2003 high in sequence from 4 to 1
//delay "motorSpeed" between each pin setting (to determine speed)

void clockwise(){
  // 1
  digitalWrite(motorPin4, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin1, LOW);
  delay(motorSpeed);
  // 2
  digitalWrite(motorPin4, HIGH);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin1, LOW);
  delay (motorSpeed);
  // 3
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin1, LOW);
  delay(motorSpeed);
  // 4
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin1, LOW);
  delay(motorSpeed);
  // 5
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin1, LOW);
  delay(motorSpeed);
  // 6
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin1, HIGH);
  delay (motorSpeed);
  // 7
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin1, HIGH);
  delay(motorSpeed);
  // 8
  digitalWrite(motorPin4, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin1, HIGH);
  delay(motorSpeed);
}



* stepper.png (195.18 KB, 500x500 - viewed 1101 times.)

* X113687.png (37.93 KB, 1600x1200 - viewed 2994 times.)
« Last Edit: December 31, 2011, 04:44:03 pm by celem » Logged

Offline Offline
Edison Member
*
Karma: 8
Posts: 1341
If you're not living on the Edge, you're taking up too much space!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've asked here in the motor forum.  I have the same hardware.  How do I make it go in reverse?  I tried using step(-64) in the library, it only goes forward.  Does this work for you?  If not, should I use your code instead?  If so, who not for me?
Logged

If you fall... I'll be there for you!
-Floor

Skype Brighteyes3333
(262) 696-9619

Offline Offline
Jr. Member
**
Karma: 3
Posts: 52
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you use my code (above) counterclockwise() for one direction, clockwise() for the other. It works!
Logged

Offline Offline
Edison Member
*
Karma: 8
Posts: 1341
If you're not living on the Edge, you're taking up too much space!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks!  Will try it.  Why doesn't the library work?
8 codes required for 28BYJ?
Only 4 in Stepper library?
Can anyone verify this?
Logged

If you fall... I'll be there for you!
-Floor

Skype Brighteyes3333
(262) 696-9619

Offline Offline
Jr. Member
**
Karma: 3
Posts: 52
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Eight steps because the motor requires eight steps. See the manufacturer's spec sheet at http://tinyurl.com/6tt337n. I attempted to attach it but the forum complains that the upload area is full. However, the stepper library can be made to work. See: http://arduino-info.wikispaces.com/SmallSteppers
« Last Edit: January 11, 2012, 07:34:34 am by celem » Logged

Offline Offline
Edison Member
*
Karma: 8
Posts: 1341
If you're not living on the Edge, you're taking up too much space!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The proper sequence is what I'm missing for reverse?
1,3,2,4 if I were using Arduino pins 1-4.
4,6,5,7 for my pins.
4,5,6,7 only goes forward?
Logged

If you fall... I'll be there for you!
-Floor

Skype Brighteyes3333
(262) 696-9619

Offline Offline
Edison Member
*
Karma: 8
Posts: 1341
If you're not living on the Edge, you're taking up too much space!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What is the advantage of using 8 sequences or phases in your code instead of 4?
More torque?
More speed?
Will try to measure it.
Logged

If you fall... I'll be there for you!
-Floor

Skype Brighteyes3333
(262) 696-9619

Offline Offline
Jr. Member
**
Karma: 3
Posts: 52
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I do not personally know of a specific advantage other than this is how the manufacturer says that it should be done. It is intuitive that the manufacturer would not arbitrarily specify eight steps for no reason whatsoever. To turn the question around, do you anticipate some advantage for you to use the library function?
Logged

Offline Offline
Edison Member
*
Karma: 8
Posts: 1341
If you're not living on the Edge, you're taking up too much space!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

No. It is a very minor advantage of simplicity.  Certainly I will use yours if there is any difference in performance.  Will let you know what I have measured.
Logged

If you fall... I'll be there for you!
-Floor

Skype Brighteyes3333
(262) 696-9619

Offline Offline
Edison Member
*
Karma: 8
Posts: 1341
If you're not living on the Edge, you're taking up too much space!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I was getting about 7RPM using 1,2,3,4 sequence in library.
15RPM with decent torque using 1,3,2,4 in library.
35RPM with your code and more torque!
I can't even stop it with my finger.
The improvement is like night and day.
You have to increase the speed gradually during ~10ms to achieve 35RPM.
Thanks!
Logged

If you fall... I'll be there for you!
-Floor

Skype Brighteyes3333
(262) 696-9619

Offline Offline
Jr. Member
**
Karma: 3
Posts: 52
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

sbright33 - Thank you for reporting your test results. 8 is better than 4, after all.
Logged

Offline Offline
God Member
*****
Karma: 1
Posts: 547
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The 8 step is called a half step, on alternate steps one winding is powered down. One note, you would be best to use bitmasks and port writes so that all motor field changes happen in unison whereas your code has them happening sequentially.
Logged

Offline Offline
Jr. Member
**
Karma: 3
Posts: 52
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes, I considered trying the bitmasks but was a bit lazy when I wrote the code.
Logged

Offline Offline
Edison Member
*
Karma: 8
Posts: 1341
If you're not living on the Edge, you're taking up too much space!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It's a work in progress...
Will comment more when it's finished.
Questions?

Code:
// This Arduino example demonstrates bidirectional operation of a
// 28BYJ-48, which is readily available on eBay, using a ULN2003
// interface board to drive the stepper. The 28BYJ-48 motor is a 4-
// phase, 8-beat motor, geared down by a factor of 64. One bipolar
// winding is on motor pins 1 & 3 and the other on motor pins 2 & 4.
// Refer to the manufacturer's documentation of  Changzhou Fulling
// Motor Co., Ltd., among others.  The step angle is 5.625/64 and the
// operating Frequency is 100pps. Current draw is 92mA. 

const int motorPin1 = 4; // Blue   - 28BYJ48 pin 1
const int motorPin2 = 5; // Pink   - 28BYJ48 pin 2
const int motorPin3 = 6; // Yellow - 28BYJ48 pin 3
const int motorPin4 = 7; // Orange - 28BYJ48 pin 4
                                // Red    - 28BYJ48 pin 5 VCC
int motorSpeed=3000;            // set stepper speed
float err=0;
void setup() {
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
  pinMode(motorPin4, OUTPUT);
  //Serial.begin(115200);
}
void loop(){
//long m=millis();
//Serial.println(millis()-m);

if(random(4))
degrpm(random(2),80*(random(8)+1),3200);
else delay(500);

//degrpmslowCool(1,long(360)*100*5,5*60);
//degrpm(1,4500,3000);delay(1000);
}
void rev(boolean bcw, long revo) { 
long step2=revo*64*8-12; //not exactly right?
int rpm100=500;
if(bcw) cwss(12,rpm100); //ramp up speed
else   ccwss(12,rpm100);
for(long i=0;i<step2;i++)
  if(bcw)cw(); else ccw();
off();
}
void degrpmslowCool(boolean bcw, long deg100, int rph100) { 
//ccw only, more torque, less current, less heat
motorSpeed=1200;
int step2=deg100*64*8/360/100; //rounded down
int d=long(351500)/2/rph100; //div 2? see stepper.xls
for(int i=0;i<step2;i++) {
ccw4st1(); off(); delay(d); //cools while off
ccw4st2(); off(); delay(d);
} //for
off();
}
void degrpmslowHot(boolean bcw, long deg100, int rph100) { 
//ccw only, more torque
motorSpeed=1200;
int step2=deg100*64*8/360/100; //rounded down
int d=long(351500)/2/rph100; //div 2? see stepper.xls
for(int i=0;i<step2;i++) {
ccw4st1(); delay(d);
ccw4st2(); delay(d);
} //for
off();
}
void degrpmslow2(boolean bcw, long deg100, int rph100) { 
//ccw only, more torque, less current, less heat
motorSpeed=1200;
int step2=deg100*64*8/360/100; //rounded down
int d=long(351500)/2/rph100; //div 2? see stepper.xls
for(int i=0;i<step2;i++) {
ccw4st1(); off(); delay(d/4); st1(); delay(d/2); off(); delay(d/4);
ccw4st2(); off(); delay(d/4); st2(); delay(d/2); off(); delay(d/4);
} //for
off();
}
void degrpm(boolean bcw, long deg100, int rpm100) { 
//max 64 turns or 23,000 deg or 2,300,000 deg100 long is bigger
//max 3500 rpm100 with 12v
int step2=deg100*64*8/360/100; //rounded down
if(rpm100<50)rpm100=50; //minimum should use degrpmslow()
rpm100=long(1463600)/rpm100-20;  //see stepper.xls
if(bcw) cwss(step2,rpm100);
else   ccwss(step2,rpm100);

float movedeg=float(step2)*360/64/8;  //float library adds 2K size to sketch
//Serial.println(movedeg);
//Serial.println(movedeg-(float)deg100/100);  //moved too little only?
//ccw4st1 can help this
err+=(movedeg-(float)deg100/100);
if(err<-1) {
motorSpeed=1200;
if(bcw) cw(); else ccw();
err+=(float(360)/64/8);
//Serial.print("err=");Serial.println(err);
} //if err
off();
}
void ccwss(int steps, int speed) {
//900 self starting 5v motor 5v ps
//800 most of 100% torque
//700 less torque
//600 almost none
//5v motor 12v supply:
//700 self starting
//400 decent torque
//6.6v 20RPM
//5V 10RPM strong
//if(speed<700) steps-=10;
//ramp up speed
motorSpeed=3000; if(speed<1200) {ccw(); ccw(); steps-=2;}
motorSpeed=1200; if(speed<1200) {ccw(); ccw(); steps-=2;}
motorSpeed=800;  if(speed<800 ) {ccw(); ccw(); steps-=2;}
motorSpeed=700;  if(speed<700 ) for(int i=0;i<4;i++) {ccw(); steps--;}
motorSpeed=speed; for(int i=0;i<steps;i++) ccw();  //64*8 is 1 rev
}
void cwss(int steps, int speed) {
motorSpeed=3000; if(speed<1200) {cw(); cw(); steps-=2;}
motorSpeed=1200; if(speed<1200) {cw(); cw(); steps-=2;}
motorSpeed=800;  if(speed<800 ) {cw(); cw(); steps-=2;}
motorSpeed=700;  if(speed<700 ) for(int i=0;i<4;i++) {cw(); steps--;}
motorSpeed=speed; for(int i=0;i<steps;i++) cw();  //64*8 is 1 rev
}
void ccw4st1(){
  // 1
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delayMicroseconds(motorSpeed);
  // 2
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delayMicroseconds(motorSpeed);
  // 3
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delayMicroseconds(motorSpeed);
  // 4
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delayMicroseconds(motorSpeed);
}
void st1(){
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
}
void ccw4st2(){
  // 5
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delayMicroseconds(motorSpeed);
  // 6
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, HIGH);
  delayMicroseconds(motorSpeed);
  // 7
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delayMicroseconds(motorSpeed);
  // 8
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delayMicroseconds(motorSpeed);
}
void st2(){
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
}
void off(){
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
}
//////////////////////////////////////////////////////////////////////////////
//set pins to ULN2003 high in sequence from 1 to 4
void ccw (){
  // 1
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delayMicroseconds(motorSpeed);
  // 2
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delayMicroseconds(motorSpeed);
  // 3
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delayMicroseconds(motorSpeed);
  // 4
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delayMicroseconds(motorSpeed);
  // 5
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delayMicroseconds(motorSpeed);
  // 6
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, HIGH);
  delayMicroseconds(motorSpeed);
  // 7
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delayMicroseconds(motorSpeed);
  // 8
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delayMicroseconds(motorSpeed);
}
//////////////////////////////////////////////////////////////////////////////
//set pins to ULN2003 high in sequence from 4 to 1
void cw(){
  // 1
  digitalWrite(motorPin4, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin1, LOW);
  delayMicroseconds(motorSpeed);
  // 2
  digitalWrite(motorPin4, HIGH);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin1, LOW);
  delayMicroseconds(motorSpeed);
  // 3
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin1, LOW);
  delayMicroseconds(motorSpeed);
  // 4
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin1, LOW);
  delayMicroseconds(motorSpeed);
  // 5
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin1, LOW);
  delayMicroseconds(motorSpeed);
  // 6
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin1, HIGH);
  delayMicroseconds(motorSpeed);
  // 7
  digitalWrite(motorPin4, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin1, HIGH);
  delayMicroseconds(motorSpeed);
  // 8
  digitalWrite(motorPin4, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin1, HIGH);
  delayMicroseconds(motorSpeed);
}

Logged

If you fall... I'll be there for you!
-Floor

Skype Brighteyes3333
(262) 696-9619

Offline Offline
Edison Member
*
Karma: 8
Posts: 1341
If you're not living on the Edge, you're taking up too much space!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

New version.
You can easily microstep with move(1) and degrpm8()

Code:
#define dw digitalWrite
#define dm delayMicroseconds

const int mp1 = 4; // Blue   - 28BYJ48 pin 1
const int mp2 = 5; // Pink   - 28BYJ48 pin 2
const int mp3 = 6; // Yellow - 28BYJ48 pin 3
const int mp4 = 7; // Orange - 28BYJ48 pin 4
                                // Red    - 28BYJ48 pin 5 VCC
int motorSpeed=3000;            // set stepper speed
int stepnum=0;
float err=0;

void setup() {
  pinMode(mp1, OUTPUT);
  pinMode(mp2, OUTPUT);
  pinMode(mp3, OUTPUT);
  pinMode(mp4, OUTPUT);
  //Serial.begin(115200);
}
void loop(){
//long m=millis();
//Serial.println(millis()-m);
//if(random(4)) degrpm8(random(2),9*(random(20)+2),3200); else delay(100);
//degrpmslowCool4(1,long(360)*100*5,10*60);
//for(int i=0;i<90;i++) {degrpm(1,400,800);delay(50);}
//for(int i=0;i<8;i++) degrpm8(0,4500,2400);
//revRestart(1,2,2000,4);
//does not work 5v for(int i=0;i<500;i++){move(1); off(); delay(1);}
//for(int i=0;i<500;i++){move(1); off(); delay(1);} //<5ms ok w 12v Cool4 better
degrpm(1,180*100,2000);
//ramp(1,2000);
off();delay(500);
}
void ramp(boolean bcw, int rpm100) {
//past 1200 it ramps in cwss() also that's bad
for(int i=50;i<1200;i+=100) //1200 or rpm100 for <1200
degrpmEZ(bcw,900,i); //<900deg ignores speed
revRestart(bcw,2,rpm100,1);
}  
void revRestart(boolean bcw, long revo, int rpm100, int xinrev) {
//xinrev small only
//in case it gets stuck due to torque load spike
for(long i=0;i<revo*xinrev;i++)
degrpm(bcw,36000/xinrev,rpm100);
}
void rev(boolean bcw, long revo) {  
long step2=revo*64*8-12; //not exactly right?
int rpm100=500;
if(bcw) cwss(12,rpm100); //ramp up speed
else   ccwss(12,rpm100);
for(long i=0;i<step2;i++)
  if(bcw)cw(); else ccw();
off();
}
void degrpmslowCool4(boolean bcw, long deg100, int rph100) {  
//ccw only, more torque, less current, less heat, most efficient code for maH
//but 4x as jerky
motorSpeed=1000;
int step2=deg100*64*8/360/100/2; //rounded down
int d=long(351500)*2/rph100; //div 2? see stepper.xls was /2 now *2
for(int i=0;i<step2;i++) {
ccw(); ccw(); off(); delay(d);
} //for
off();
}
void degrpmslowCool(boolean bcw, long deg100, int rph100) {  
//ccw only, more torque, less current, less heat
motorSpeed=1500; //why 1500 needed?
int step2=deg100*64*8/360/100; //rounded down
int d=long(351500)/2/rph100; //div 2? see stepper.xls
for(int i=0;i<step2;i++) {
ccw4st1(); off(); delay(d); //cools while off
ccw4st2(); off(); delay(d);
} //for
off();
}
void degrpmslowHot(boolean bcw, long deg100, int rph100) {  
//ccw only, more torque, hot w 12v
motorSpeed=1000;
int step2=deg100*64*8/360/100; //rounded down
int d=long(351500)/2/rph100; //div 2? see stepper.xls
for(int i=0;i<step2;i++) {
ccw4st1(); delay(d);
ccw4st2(); delay(d);
} //for
off();
}
void degrpmslow2(boolean bcw, long deg100, int rph100) {  
//ccw only, more torque, less current, less heat, 50% duty cycle
//compromise Hot,Cool
motorSpeed=1000; //12v
int step2=deg100*64*8/360/100; //rounded down
int d=long(351500)/2/rph100; //div 2? see stepper.xls
for(int i=0;i<step2;i++) {
ccw4st1(); off(); delay(d/4); st1(); delay(d/2); off(); delay(d/4);
ccw4st2(); off(); delay(d/4); st2(); delay(d/2); off(); delay(d/4);
} //for
off();
}
void degrpmEZ(boolean bcw, long deg100, int rpm100) {  
//max 64 turns or 23,000 deg or 2,300,000 deg100 long is bigger
//max 3500 rpm100 with 12v
int step2=deg100*64*8/360/100; //rounded down
if(rpm100<50)rpm100=50; //minimum should use degrpmslow()
rpm100=long(1463600)/rpm100-20;  //see stepper.xls
if(bcw) cwss(step2,rpm100);
else   ccwss(step2,rpm100);
}
void degrpm(boolean bcw, long deg100, int rpm100) {  
//max 64 turns or 23,000 deg or 2,300,000 deg100 long is bigger
//max 3500 rpm100 with 12v
int step2=deg100*64*8/360/100; //rounded down
if(rpm100<50)rpm100=50; //minimum should use degrpmslow()
rpm100=long(1463600)/rpm100-20;  //see stepper.xls
if(bcw) cwss(step2,rpm100);
else   ccwss(step2,rpm100);

//with this code you can step by 2.00 deg 180x will be 360+-1
//0.50 deg 720x works to 360
//even though step size is >0.50 or 0.72?
float movedeg=float(step2)*360/64/8;  //float library adds 2K size to sketch
//Serial.println(movedeg);
//Serial.println(movedeg-(float)deg100/100);  //moved too little only?
//ccw4st1 can help this
err+=(movedeg-(float)deg100/100);
if(err<-1) {
motorSpeed=1200;
if(bcw) cw(); else ccw();
err+=(float(360)/64/8);
//Serial.print("err=");Serial.println(err);
} //if err
//soft stop moves further than it should
//if(bcw) cwss(15,2000);
//else   ccwss(15,2000);
delay(10); //so it stops and holds before off in loop
//off();
}
void degrpm8(boolean bcw, long deg100, int rpm100) {  
//max 8 turns
//max <<3500 rpm100 with 12v cuz no ramping ~17RPM
const int min2start=1200; //700 12v, 1200 5v
int step2=deg100*64*64/360/100; //rounded down
if(rpm100<50)rpm100=50; //minimum should use degrpmslow()
rpm100=long(1463600)/rpm100-20;  //see stepper.xls same SAME
motorSpeed=rpm100;
if(motorSpeed<min2start)motorSpeed=min2start;
for(int i=0;i<step2;i++) {
  if(bcw)stepnum++; else stepnum--;
  st07();
  }
//was if(bcw)cwss(step2,rpm100); else ccwss(step2,rpm100);
//does not adjust for err like degrpm cuz step 0.088 or 1/11 deg
float movedeg=float(step2)*360/64/64;  //float library adds 2K size to sketch
//Serial.println(movedeg);
err+=(movedeg-(float)deg100/100);
//Serial.println(err);
//if(err<-1) {motorSpeed=1200; if(bcw) cw(); else ccw(); err+=(float(360)/64/8);}
//off();
}
void move(boolean bcw){
motorSpeed=1200;
if(bcw)stepnum++; else stepnum--;
st07();
}
void ccwss(int steps, int speed) {
//900 self starting 5v motor 5v ps
//800 most of 100% torque
//700 less torque
//600 almost none
//5v motor 12v supply:
//700 self starting
//400 decent torque
//6.6v 20RPM
//8.3v load 8.5v float 6x NiMh
//20RPM strong 28RPM weak
//15RPM 100% torque
//does not overheat
//5V 10RPM strong
//5V 20RPM weak
//5V 24RPM no torque
//12V 20RPM self start 35 max speed
//if(speed<700) steps-=10;
//ramp up speed
motorSpeed=1000; //<12 steps, 800 for 12v
if(steps>=12) {
motorSpeed=3000; if(speed<1200) {ccw(); ccw(); steps-=2;}
motorSpeed=1200; if(speed<1200) {ccw(); ccw(); steps-=2;}
motorSpeed=800;  if(speed<800 ) {ccw(); ccw(); steps-=2;}
motorSpeed=700;  if(speed<700 ) for(int i=0;i<4;i++) {ccw(); steps--;}
motorSpeed=speed;
} //if
for(int i=0;i<steps;i++) ccw();  //64*8 is 1 rev
}
void cwss(int steps, int speed) {
motorSpeed=1000; //<12 steps, 800 for 12v
if(steps>=12) {
motorSpeed=3000; if(speed<1200) {cw(); cw(); steps-=2;}
motorSpeed=1200; if(speed<1200) {cw(); cw(); steps-=2;}
motorSpeed=800;  if(speed<800 ) {cw(); cw(); steps-=2;}
motorSpeed=700;  if(speed<700 ) for(int i=0;i<4;i++) {cw(); steps--;}
motorSpeed=speed;
} //if
for(int i=0;i<steps;i++) cw();  //64*8 is 1 rev
}
void ccw4st1(){
  // 1
  dw(mp1, HIGH);
  dw(mp2, LOW);
  dw(mp3, LOW);
  dw(mp4, LOW);
  dm(motorSpeed);
  // 2
  dw(mp1, HIGH);
  dw(mp2, HIGH);
  dw(mp3, LOW);
  dw(mp4, LOW);
  dm(motorSpeed);
  // 3
  dw(mp1, LOW);
  dw(mp2, HIGH);
  dw(mp3, LOW);
  dw(mp4, LOW);
  dm(motorSpeed);
  // 4
  dw(mp1, LOW);
  dw(mp2, HIGH);
  dw(mp3, HIGH);
  dw(mp4, LOW);
  dm(motorSpeed);
}
void st1(){
  dw(mp1, LOW);
  dw(mp2, HIGH);
  dw(mp3, HIGH);
  dw(mp4, LOW);
}
void ccw4st2(){
  // 5
  dw(mp1, LOW);
  dw(mp2, LOW);
  dw(mp3, HIGH);
  dw(mp4, LOW);
  dm(motorSpeed);
  // 6
  dw(mp1, LOW);
  dw(mp2, LOW);
  dw(mp3, HIGH);
  dw(mp4, HIGH);
  dm(motorSpeed);
  // 7
  dw(mp1, LOW);
  dw(mp2, LOW);
  dw(mp3, LOW);
  dw(mp4, HIGH);
  dm(motorSpeed);
  // 8
  dw(mp1, HIGH);
  dw(mp2, LOW);
  dw(mp3, LOW);
  dw(mp4, HIGH);
  dm(motorSpeed);
}
void st2(){
  dw(mp1, HIGH);
  dw(mp2, LOW);
  dw(mp3, LOW);
  dw(mp4, HIGH);
}
void off(){
  dw(mp1, LOW);
  dw(mp2, LOW);
  dw(mp3, LOW);
  dw(mp4, LOW);
}
void st07(){
if(stepnum==-1)stepnum=7;
if(stepnum==8)stepnum=0;
switch(stepnum){
case 0:
  dw(mp4, HIGH);
  dw(mp3, LOW);
  dw(mp2, LOW);
  dw(mp1, LOW);
  dm(motorSpeed);
  break;
case 1:
  dw(mp4, HIGH);
  dw(mp3, HIGH);
  dw(mp2, LOW);
  dw(mp1, LOW);
  dm(motorSpeed);
  break;
case 2:
  dw(mp4, LOW);
  dw(mp3, HIGH);
  dw(mp2, LOW);
  dw(mp1, LOW);
  dm(motorSpeed);
  break;
case 3:
  dw(mp4, LOW);
  dw(mp3, HIGH);
  dw(mp2, HIGH);
  dw(mp1, LOW);
  dm(motorSpeed);
  break;
case 4:
  dw(mp4, LOW);
  dw(mp3, LOW);
  dw(mp2, HIGH);
  dw(mp1, LOW);
  dm(motorSpeed);
  break;
case 5:
  dw(mp4, LOW);
  dw(mp3, LOW);
  dw(mp2, HIGH);
  dw(mp1, HIGH);
  dm(motorSpeed);
  break;
case 6:
  dw(mp4, LOW);
  dw(mp3, LOW);
  dw(mp2, LOW);
  dw(mp1, HIGH);
  dm(motorSpeed);
  break;
case 7:
  dw(mp4, HIGH);
  dw(mp3, LOW);
  dw(mp2, LOW);
  dw(mp1, HIGH);
  dm(motorSpeed);
  break;
}
}
Logged

If you fall... I'll be there for you!
-Floor

Skype Brighteyes3333
(262) 696-9619

Pages: [1] 2 3 ... 10   Go Up
Jump to: