public
Created

Servo and stepper easing example

  • Download Gist
stepper2small.pde
Processing
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
// This Arduino example demonstrates bidirectional operation of a
// 28BYJ-48, which is readily available on eBay for $4.25 inc shipping,
// using a ULN2003 interface board to drive the stepper.
#include <Servo.h>
#define dw digitalWrite
#define dm delayMicroseconds
#define wr32 Serial.write(32);
#define wr13 Serial.write(10);
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, period actually
int stepnum=0; // current microstep 0-7
int movecnt=0; // running total of steps taken in move(), &=4095 in moveto
long ems,mst,m; // millis()
int maxmove=0; // ease()
float prev=45; // eo_servo
Servo myservo; // 22-155 deg
 
void setup() {
pinMode(mp1, OUTPUT);
pinMode(mp2, OUTPUT);
pinMode(mp3, OUTPUT);
pinMode(mp4, OUTPUT);
pinMode(13, OUTPUT); //onboard LED
//Serial.begin(9600);
myservo.attach(11); //pin 11 end of row
ems=micros(); //init easeoften() end of setup
}
void loop(){
//if(!eo_servo()){
if(!(m=easeoften(0,0))){
//if(!(m=eo_degrpm(95,1000))){
//Serial.println(maxmove/11.377);
//Serial.println(millis()/1000.0);
//myservo.write(140);delay(300);myservo.write(22);delay(300);
while(1);
}
//delay(10); // <chgms/multsp-10
delayMicroseconds(m/2); //m/2 safe
}
int eo_servo(){
//multsp <1 jerky >4 plateau shaped
const float cellD2=6514; //ease.xls
const float multsp=3,multdeg=1.1;
const int degoffset=-22; //-22
const int chgms=74,mspa[]={ //from easeoften()
6450,3640,2413,1751,1338,1068,892,785,732,732,785,892,1068,1338,1747,2422,3640,6450,21015,
-21015,-6450,-3640,-2422,-1747,-1338,-1068,-892,-785,-732,-732,-785,-892,-1068,-1338,-1751,-2413,-3640,-6450,0};
int ii=chgms/multsp;
//int n=millis();
while(((m=millis())%ii)>5); //always catch 0? servo interrupt skipped this ==0
//Serial.print(m-n);wr32
int i=mspa[m/ii];
if(!i)return(0);
prev+=cellD2/i;
int deg=(prev+0.5+degoffset)*multdeg;
//Serial.print(m/ii);wr32
//Serial.print(prev);wr32
//Serial.print(cellD2/i);wr32
//Serial.print(deg);wr32
myservo.write(deg);
return(deg);
}
int eo_degrpm(int deg, int rpm100) {
//no floats used in easeoften()
const int chgms=74,rpm=2000,degmov=90; //from ease.xls
deg=(float(deg)/degmov-1)*chgms+0.5;
rpm100=(float(rpm100)/rpm-1)*chgms+0.5;
while(easeoften(deg,rpm100));return(0);
//return(easeoften(deg,rpm100)); //calcs floats every iteration
}
int easeoften(int adjdist, int adjspeed){
//do not change adjspeed,dist once you begin
//call every << return() micros about r/2
//line interval 74ms 20RPM see ease.xls
const int chgms=74,mspa[]={
6450,3640,2413,1751,1338,1068,892,785,732,732,785,892,1068,1338,1747,2422,3640,6450,21015,
-21015,-6450,-3640,-2422,-1747,-1338,-1068,-892,-785,-732,-732,-785,-892,-1068,-1338,-1751,-2413,-3640,-6450,0};
int easi=millis()/(chgms-adjspeed+adjdist); //might be late, plus adjspeed is shorter cuz faster
long i=abs(mspa[easi]);
if(!i)return(0); //done
long j=abs(mspa[easi+1]); //next speed wrong 0 during last line
i-=long(adjspeed)*i/chgms;
j-=long(adjspeed)*j/chgms; //not important used for return only
boolean bcw=(mspa[easi]>0);
if(bcw)stepnum++; else stepnum--;
if(bcw)movecnt++; else movecnt--;
if(movecnt>maxmove)maxmove=movecnt;
motorSpeed=1; //1?
ems+=i;
//no time to print
//Serial.print(movecnt);wr32
//Serial.print(easi);wr32
//Serial.print(ems);wr13
while(micros()<ems){ //blocking do something else too?
};
st07();
//if(movecnt%55==0){ //5 deg
//Serial.print(movecnt/11.377);wr32}
if(j<i)i=j; //j or i smaller guess worst case, i is usually correct, so wrong 1/2 of the time
return(i); //could be too short to wait for next step, j not adj4speed above?, check micros()>ems+i-100 in loop
}
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);
break;
case 1:
dw(mp4, HIGH);
dw(mp3, HIGH);
dw(mp2, LOW);
dw(mp1, LOW);
break;
case 2:
dw(mp4, LOW);
dw(mp3, HIGH);
dw(mp2, LOW);
dw(mp1, LOW);
break;
case 3:
dw(mp4, LOW);
dw(mp3, HIGH);
dw(mp2, HIGH);
dw(mp1, LOW);
break;
case 4:
dw(mp4, LOW);
dw(mp3, LOW);
dw(mp2, HIGH);
dw(mp1, LOW);
break;
case 5:
dw(mp4, LOW);
dw(mp3, LOW);
dw(mp2, HIGH);
dw(mp1, HIGH);
break;
case 6:
dw(mp4, LOW);
dw(mp3, LOW);
dw(mp2, LOW);
dw(mp1, HIGH);
break;
case 7:
dw(mp4, HIGH);
dw(mp3, LOW);
dw(mp2, LOW);
dw(mp1, HIGH);
break;
}
dm(motorSpeed);
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.