Chuck: The steppers I use are the cheapest I could find. 28BYJ-48. They are available at SparkFun but then you have to buy the drivers. From BangGood they sell them for a couple of dollars each, and include a little board that provides the LM2003 drivers plus pins for other connections from the Arduino. Those cheapest ones have a 64:1 reduction, so they don’t turn so quickly. The ones from Sparkfun have a 16:1 reductio, otherwise identical, and make the robot go faster. I found them on Ebay (you need to look for the 16:1 reduction in the description, and they work fine, but buy some of the other ones so you can get the driver chips. I use a Arduino Uno (the smallest one) for the computer. The four wires from the motor output from the mbot board go to 4 input pins on the Arduino, and two sets of 4 output pins go to drive the two LM2003 driver chips (which have the sockets for the cable to the stepper built right into the board. I power the driver board with 8V as it makes the stepper move more positively. Have a look at the program (included below) and of course I can answer questions. This setup runs all the motor commands available for the mbot, just as if you were using the DC motors. Here is the code:
/*
Code to convert mbot motor output to stepper motor commands,
using arduino digital inputs to read the PWM motor outputs
(providing speed info) and other stepper code
to drive the 2 small unipolor stepper motors
using LM2003 chips. Motors can be run together or
separately, in either direction and at different speeds.
PWM motor outputs are read digitally and converted to
analog speed values, which are then used to set the delay
times between stepper motor pulses and hence the stepper motor
speed. Before each iteration, check if there is enough time
for the currently active motors. Otherwise a new mbot motor read
is made every 1.2 ms, which is the time for one
complete PWM cycle from the mbot motor output
05/23/2016 Eric Frank
02/06/2016 Modified for testing so not requiring
input from the mbot
27/06/2016 changed order of digital out pins
01/07/2016 New way to read PWM speed from mbot. Digitally read
mbot outputs on all 4 wires as fast as possible.
60 reads (of each of 4 inputs) is 1 PWM cycle.
So sum the 60 values (T is high, F is low) to get the speed.
60 is max speed (255 for mbot), 30 is half speed (127
for mbot), etc.
14/07/2016 basically working, although all speeds are set here to
give max rotation speed
31/08/2016 works well when driven by mbot motor output
04/09/2016 modify to get new motor data only every 20 ms and
keep stepping with current data in between new data reads
*/
long int M1F=0; //Motor M1, forward
long int M1B=0; //Motor M1, backward
long int M2F=0; //Motor M2, etc
long int M2B=0;
int Steps1 = 0;
int Steps2 = 0;
int i;
//defaults to forward
int Dir1 = 2;// 0 is forward, 1 is backwards
int Dir2 = 2;// 2 is don’t step & turn off power
long int Speed2LT = 60000; //LoopDelay=90000/speed? should be 60000?
long int LoopDelay1=0; //how fast can this go?
long int LoopDelay2=0; //
long WaitTime=20; //# of ms to wait for new data collection
unsigned long NextCycle=0; //# of ms to wait for new data collection
unsigned long NextTime1=0;
unsigned long NextTime2=0;
//Stepper1
#define OUT11 2
#define OUT12 3
#define OUT13 4
#define OUT14 5
//Stepper2
#define OUT21 6
#define OUT22 7
#define OUT23 8
#define OUT24 9
void setup() { //these are the inputs to the LM2003 stepper drivers
//Serial.begin(115200);
pinMode(OUT11, OUTPUT);
pinMode(OUT12, OUTPUT);
pinMode(OUT13, OUTPUT);
pinMode(OUT14, OUTPUT);
pinMode(OUT21, OUTPUT);
pinMode(OUT22, OUTPUT);
pinMode(OUT23, OUTPUT);
pinMode(OUT24, OUTPUT);
}
void loop() {
//Initialize motor controls
M1F = 0; M1B = 0; M2F = 0; M2B = 0;
Dir1 = 2; Dir2 = 2;
//read motor data from mbot
for (int i=0; i<60; i++)
{M1F += digitalRead(14); M1B += digitalRead(15);
M2F += digitalRead(16); M2B += digitalRead(17);}
//calculate step rates
if (M1F>1) //move M1 forward
{Dir1 = 0; LoopDelay1 = Speed2LT/M1F;}
if (M1B>1) //move M1 backwards
{Dir1 = 1; LoopDelay1 = Speed2LT/M1B;}
if (M2F>1) //move M2 forward
{Dir2 = 0; LoopDelay2 = Speed2LT/M2F;}
if (M2B>1) //move M2 backwards
{Dir2 = 1; LoopDelay2 = Speed2LT/M2B;}
// Serial.print(M1B); Serial.print(" "); Serial.println(LoopDelay1);
//if ((Dir1==2) && (Dir2==2)) reset(); //no motor runing so turn them off
NextCycle = millis() + WaitTime;
if (millis()<= NextCycle){ //run steppers until time for next data read
if (Dir1 != 2) //M1 should move
{if(micros() >= NextTime1) //move if step delay big enough
{NextTime1 = (micros() + LoopDelay1); stepper1();}
}
if (Dir2 != 2) //M2 should move
{if(micros() >= NextTime2) //move if step delay big enough
{NextTime2 = (micros() + LoopDelay2); stepper2();}
}
}
}
// stepper1 and 2 provide the outputs to the LM2003 chips that
// drive the stepper motors (M1 and M2)
void stepper1(){
switch(Steps1)
{case 0:
digitalWrite(OUT11, LOW);
digitalWrite(OUT12, LOW);
digitalWrite(OUT13, LOW);
digitalWrite(OUT14, HIGH);
break;
case 1:
//Serial.println(i);
digitalWrite(OUT11, LOW);
digitalWrite(OUT12, LOW);
digitalWrite(OUT13, HIGH);
digitalWrite(OUT14, HIGH);
break;
case 2:
digitalWrite(OUT11, LOW);
digitalWrite(OUT12, LOW);
digitalWrite(OUT13, HIGH);
digitalWrite(OUT14, LOW);
break;
case 3:
digitalWrite(OUT11, LOW);
digitalWrite(OUT12, HIGH);
digitalWrite(OUT13, HIGH);
digitalWrite(OUT14, LOW);
break;
case 4:
digitalWrite(OUT11, LOW);
digitalWrite(OUT12, HIGH);
digitalWrite(OUT13, LOW);
digitalWrite(OUT14, LOW);
break;
case 5:
digitalWrite(OUT11, HIGH);
digitalWrite(OUT12, HIGH);
digitalWrite(OUT13, LOW);
digitalWrite(OUT14, LOW);
break;
case 6:
digitalWrite(OUT11, HIGH);
digitalWrite(OUT12, LOW);
digitalWrite(OUT13, LOW);
digitalWrite(OUT14, LOW);
break;
case 7:
//Serial.println(i);
digitalWrite(OUT11, HIGH);
digitalWrite(OUT12, LOW);
digitalWrite(OUT13, LOW);
digitalWrite(OUT14, HIGH);
break;
default:
digitalWrite(OUT11, LOW);
digitalWrite(OUT12, LOW);
digitalWrite(OUT13, LOW);
digitalWrite(OUT14, LOW);
break;
}
if(Dir1==1) Steps1++;
if(Dir1==0) Steps1–;
if(Steps1>7) Steps1=0;
if(Steps1<0) Steps1=7;
}
void stepper2(){
switch(Steps2)
{case 0:
digitalWrite(OUT21, LOW);
digitalWrite(OUT22, LOW);
digitalWrite(OUT23, LOW);
digitalWrite(OUT24, HIGH);
break;
case 1:
digitalWrite(OUT21, LOW);
digitalWrite(OUT22, LOW);
digitalWrite(OUT23, HIGH);
digitalWrite(OUT24, HIGH);
break;
case 2:
digitalWrite(OUT21, LOW);
digitalWrite(OUT22, LOW);
digitalWrite(OUT23, HIGH);
digitalWrite(OUT24, LOW);
break;
case 3:
digitalWrite(OUT21, LOW);
digitalWrite(OUT22, HIGH);
digitalWrite(OUT23, HIGH);
digitalWrite(OUT24, LOW);
break;
case 4:
digitalWrite(OUT21, LOW);
digitalWrite(OUT22, HIGH);
digitalWrite(OUT23, LOW);
digitalWrite(OUT24, LOW);
break;
case 5:
digitalWrite(OUT21, HIGH);
digitalWrite(OUT22, HIGH);
digitalWrite(OUT23, LOW);
digitalWrite(OUT24, LOW);
break;
case 6:
digitalWrite(OUT21, HIGH);
digitalWrite(OUT22, LOW);
digitalWrite(OUT23, LOW);
digitalWrite(OUT24, LOW);
break;
case 7:
digitalWrite(OUT21, HIGH);
digitalWrite(OUT22, LOW);
digitalWrite(OUT23, LOW);
digitalWrite(OUT24, HIGH);
break;
default:
digitalWrite(OUT21, LOW);
digitalWrite(OUT22, LOW);
digitalWrite(OUT23, LOW);
digitalWrite(OUT24, LOW);
break;
}
if(Dir2==1) Steps2++;
if(Dir2==0) Steps2–;
if(Steps2>7) Steps2=0;
if(Steps2<0) Steps2=7;
}
void reset() //turn off power to steppers
{digitalWrite(OUT11, LOW);
digitalWrite(OUT12, LOW);
digitalWrite(OUT13, LOW);
digitalWrite(OUT14, LOW);
digitalWrite(OUT21, LOW);
digitalWrite(OUT22, LOW);
digitalWrite(OUT23, LOW);
digitalWrite(OUT24, LOW);
}
End of code. More comments in another post on this thread. Eric