Unipolar Stepper Troubles (SBT0811 +28BYJ48)

Hello,

I've tried several tutorials and the built in examples to no avail.
Sorry if any of this sounds dumb I started very recently playing with arduino and don't have any programming knowledge.

Only these two options have managed to move the damn thing (I don't think the second one could suit my needs, see below)

  1. http://www.instructables.com/id/BYJ48-Stepper-Motor/
  2. Custom "unistep" library and code from this guy
    http://www.crazy-logic.co.uk/projects/computing/arduino-unistep

I just want to modify one of these two to suit my needs, nothing fancy really but I did not succeed.

  • Initiate movement following an input from a sensor (a simple High input on one of the digital pins should do it).
  • Move a certain amount of steps (degrees) (the stepper has 4096 steps apparently)
  • Go back after a few seconds
  • Being able to function on a power supply, without the computer. I say this because the one with the custom unistep library uses the Serial command and you actually move the stepper by pressing on a letter in the serial monitor so I don't think this could work.

Picture of setup is attached below

Thanks

Code from instructables

/*
       BYJ48 Stepper motor code
       Connect :
       IN1 >> D8
       IN2 >> D9
       IN3 >> D10
       IN4 >> D11
       VCC ... 5V Prefer to use external 5V Source
       Gnd
       written By :Mohannad Rawashdeh
      http://www.instructables.com/member/Mohannad+Rawashdeh/
         28/9/2013
      */
 
    #define IN1  8
    #define IN2  9
    #define IN3  10
    #define IN4  11
    int Steps = 0;
    boolean Direction = true;// gre
    unsigned long last_time;
    unsigned long currentMillis ;
    int steps_left=4095;
    long time;
    void setup()
    {
    Serial.begin(115200);
    pinMode(IN1, OUTPUT); 
    pinMode(IN2, OUTPUT); 
    pinMode(IN3, OUTPUT); 
    pinMode(IN4, OUTPUT); 
    // delay(1000);
 
    }
    void loop()
    {
      while(steps_left>0){
      currentMillis = micros();
      if(currentMillis-last_time>=1000){
      stepper(1); 
      time=time+micros()-last_time;
      last_time=micros();
      steps_left--;
      }
      }
       Serial.println(time);
      Serial.println("Wait...!");
      delay(2000);
      Direction=!Direction;
      steps_left=4095;
    }
 
    void stepper(int xw){
      for (int x=0;x<xw;x++){
    switch(Steps){
       case 0:
         digitalWrite(IN1, LOW); 
         digitalWrite(IN2, LOW);
         digitalWrite(IN3, LOW);
         digitalWrite(IN4, HIGH);
       break; 
       case 1:
         digitalWrite(IN1, LOW); 
         digitalWrite(IN2, LOW);
         digitalWrite(IN3, HIGH);
         digitalWrite(IN4, HIGH);
       break; 
       case 2:
         digitalWrite(IN1, LOW); 
         digitalWrite(IN2, LOW);
         digitalWrite(IN3, HIGH);
         digitalWrite(IN4, LOW);
       break; 
       case 3:
         digitalWrite(IN1, LOW); 
         digitalWrite(IN2, HIGH);
         digitalWrite(IN3, HIGH);
         digitalWrite(IN4, LOW);
       break; 
       case 4:
         digitalWrite(IN1, LOW); 
         digitalWrite(IN2, HIGH);
         digitalWrite(IN3, LOW);
         digitalWrite(IN4, LOW);
       break; 
       case 5:
         digitalWrite(IN1, HIGH); 
         digitalWrite(IN2, HIGH);
         digitalWrite(IN3, LOW);
         digitalWrite(IN4, LOW);
       break; 
         case 6:
         digitalWrite(IN1, HIGH); 
         digitalWrite(IN2, LOW);
         digitalWrite(IN3, LOW);
         digitalWrite(IN4, LOW);
       break; 
       case 7:
         digitalWrite(IN1, HIGH); 
         digitalWrite(IN2, LOW);
         digitalWrite(IN3, LOW);
         digitalWrite(IN4, HIGH);
       break; 
       default:
         digitalWrite(IN1, LOW); 
         digitalWrite(IN2, LOW);
         digitalWrite(IN3, LOW);
         digitalWrite(IN4, LOW);
       break; 
    }
    SetDirection();
    }
    } 
    void SetDirection(){
    if(Direction==1){ Steps++;}
    if(Direction==0){ Steps--; }
    if(Steps>7){Steps=0;}
    if(Steps<0){Steps=7; }
    }

Code with unistep library

#include<unistep.h>
 
 //create a stepper instance
 unistep stepper1(8,9,10,11,4096,900); //4 pins,no of steps on motor,delay
 
 
 //for serial
 int incomingByte;
 
 const int buttonPin = 2;
 
 void setup()
 {
 Serial.begin(9600);
 pinMode(buttonPin, INPUT);
 }
 
 void loop()
 {
  if (Serial.available() >0)
 {
    incomingByte=Serial.read();
  if(incomingByte == 'R')
    {stepper1.moves(2000,1);}
 }
 }

Starting with your last question:
Pls tell us if you got the 5V or 12V version of this stepper as this will make a difference.

Second:
Did you play with the IDE's examples, especially the examples with button reads?

This forum is NOT to write code for you, but to push you into the right direction. So you will be "forced" to learn how to fish - we will help you with tipps and tricks, when we see what you do/try to do.

But this has to be more than copy and paste existing code which does something, but not exactly what you want it to do.

To give you some starting points:

  1. Within loop() you need to continuously read your button and then trigger your stepper to move, when the button press was detected (hint: learn something about state change)
  2. An elegant way would then be to call a function (e.g. called forwardStepper) which then moves the stepper a certain amount of steps (=degrees, 4096 to get a 360 degree turn).
  3. From the time on when the movement has reached the final position, start a timer (millis ...) which counts until your time limit is reached (avoid to deal with delay(), which might work here as no further action is required, but you will learn a bad habit and whenever your requirements increase to do something while the idle period is ongoing - you will have aproblem with delay() ) and then
  4. call another function (e.g. backwardStepper) to issue an inverse DIR signal and send the same amount of steps to turn the stepper back into its initial position.

Having been unexpectedly busy I had to drop the matter temporarily.
Here's what I've come up with in the meantime:

Any idea why the (A) LED stays lit on the driver board ? (the 3 others B,C,D shut on and off as expected).

// https://www.youtube.com/watch?v=Bp8iVILpD24

int stepperpins[] = {2, 3, 4, 5};
int stepperCurPos = 0;

void SetupStepper() {
  for (int x = 0; x < 4; x++) pinMode(stepperpins[x], OUTPUT);
}

void MoveStepper(int direction) {
  digitalWrite(stepperpins[stepperCurPos], 0); //turn off current pin
  stepperCurPos += direction;
  if (stepperCurPos > 3) stepperCurPos = 0;
  if (stepperCurPos < 0) stepperCurPos = 3;
  digitalWrite(stepperpins[stepperCurPos], 1); //turn on new current pin
}
void setup() {
  pinMode(8, INPUT);
  SetupStepper();
}

int msdly = 3;

void loop() {
  if ( digitalRead(8) ) {
    for (int x = 0; x < 300; x++) {
      MoveStepper(1);
      delay(msdly);
    }
    for (int x = 0; x < 300; x++) {
      MoveStepper(-1);
      delay(msdly);
    }
  }
}

Your code always leaves the current phase active, so at any one time one LED will be lit
(assuming your LEDs are on pins 2,3,4,5). That is exactly what is needed for a stepper where
a phase is active at all times to hold the rotor in position.

BTW you missed a trick here:

  stepperCurPos += direction;
  if (stepperCurPos > 3) stepperCurPos = 0;
  if (stepperCurPos < 0) stepperCurPos = 3;

can be replaced by one line:

  stepperCurPos = (stepperCurPos + direction) & 3 ;

since bit-wise and implements correct modular arithmetic modulo a power of 2.
(The % operator does not since it returns negative values for negative input, since C
doesn't follow the rules of mathematics!)

This would not work:

  stepperCurPos = (stepperCurPos + direction) % 4 ;

MarkT:
Your code always leaves the current phase active, so at any one time one LED will be lit
(assuming your LEDs are on pins 2,3,4,5). That is exactly what is needed for a stepper where
a phase is active at all times to hold the rotor in position.

I see, thank you

MarkT:
BTW you missed a trick here:

  stepperCurPos += direction;

if (stepperCurPos > 3) stepperCurPos = 0;
 if (stepperCurPos < 0) stepperCurPos = 3;



can be replaced by one line:


stepperCurPos = (stepperCurPos + direction) & 3 ;



since bit-wise and implements correct modular arithmetic modulo a power of 2.
(The % operator does not since it returns negative values for negative input, since C
doesn't follow the rules of mathematics!)

This would not work:


stepperCurPos = (stepperCurPos + direction) % 4 ;

I'm not sure what you meant by that (beginner in everything relating to programming/electronics sorry).
I vaguely know about modulo math but I don't see how it is connected nor how this expression could work:

stepperCurPos = (stepperCurPos + direction) & 3 ;