0

I'm trying to get my 28BYJ-48 Stepper Motor to rotate one quarter of a revolution and then stop, but I'm having trouble implementing that in code. What I find is no matter how small I make the numbers in my code or even alter it in ways that make me think it'd work properly, I can't get it to stop rotating. Below is the helpful part of the code.

#define STEPPER  (*((volatile uint32_t *)0x4000703C))

// Move 1.8 degrees clockwise, delay is the time to wait after each step
void Stepper_CW(uint32_t delay) {
  Pt = Pt->Next[clockwise];     // circular
  STEPPER = Pt->Out; // step motor

  if(Pos==199) {      // shaft angle
    Pos = 0;         // reset
  }
  else {
    Pos--; // CW
  }
 SysTick_Wait(delay);
}

// Move 1.8 degrees counterclockwise, delay is wait after each step
void Stepper_CCW(uint32_t delay) {
  Pt = Pt->Next[counterclockwise]; // circular
  STEPPER = Pt->Out; // step motor
  if(Pos==0) {        // shaft angle
    Pos = 199;         // reset
  }
  else {
    Pos++; // CCW
  }
 SysTick_Wait(delay); // blind-cycle wait
}

// Initialize Stepper interface
void Stepper_Init(void) {
  SYSCTL_RCGCGPIO_R |= 0x08; // 1) activate port D
  SysTick_Init();
  Pos = 0;                   
  Pt = &fsm[0]; 
                                // 2) no need to unlock PD3-0
  GPIO_PORTD_AMSEL_R &= ~0x0F;      // 3) disable analog functionality on PD3-0
  GPIO_PORTD_PCTL_R &= ~0x0000FFFF; // 4) GPIO configure PD3-0 as GPIO
  GPIO_PORTD_DIR_R |= 0x0F;             // 5) make PD3-0 out
  GPIO_PORTD_AFSEL_R &= ~0x0F;          // 6) disable alt funct on PD3-0
  GPIO_PORTD_DR8R_R |= 0x0F;            // enable 8 mA drive
  GPIO_PORTD_DEN_R |= 0x0F;         // 7) enable digital I/O on PD3-0 
}

// Turn stepper motor to desired position
// (0 <= desired <= 199)
// time is the number of bus cycles to wait after each step
void Stepper_Seek(uint8_t desired, uint32_t time) {
 short CWsteps;
  if((CWsteps = (desired-Pos))<0) {
   CWsteps+=200;
  } 

// CW steps is > 100
 if(CWsteps > 100) {
   while(desired != Pos) {
     Stepper_CCW(time);
   }
 }
 else {
   while(desired != Pos) {
    Stepper_CW(time);
   } 
 }
}

Stepper_Seek gets called here...

#include <stdint.h>
#include "stepper.h"
#define T1ms 16000    // assumes using 16 MHz PIOSC (default setting for clock source)
int main(void) {
  Stepper_Init();
  Stepper_CW(T1ms);   // Pos=1; GPIO_PORTD_DATA_R=9
  Stepper_CW(T1ms);   // Pos=2; GPIO_PORTD_DATA_R=5
  Stepper_CW(T1ms);   // Pos=3; GPIO_PORTD_DATA_R=6
  Stepper_CW(T1ms);   // Pos=4; GPIO_PORTD_DATA_R=10
  Stepper_CW(T1ms);   // Pos=5; GPIO_PORTD_DATA_R=9
  Stepper_CW(T1ms);   // Pos=6; GPIO_PORTD_DATA_R=5
  Stepper_CW(T1ms);   // Pos=7; GPIO_PORTD_DATA_R=6
  Stepper_CW(T1ms);   // Pos=8; GPIO_PORTD_DATA_R=10
  Stepper_CW(T1ms);   // Pos=9; GPIO_PORTD_DATA_R=9
  Stepper_CCW(T1ms);  // Pos=8; GPIO_PORTD_DATA_R=10
  Stepper_CCW(T1ms);  // Pos=7; GPIO_PORTD_DATA_R=6
  Stepper_CCW(T1ms);  // Pos=6; GPIO_PORTD_DATA_R=5
  Stepper_CCW(T1ms);  // Pos=5; GPIO_PORTD_DATA_R=9
  Stepper_CCW(T1ms);  // Pos=4; GPIO_PORTD_DATA_R=10
  Stepper_Seek(8,T1ms);// Pos=8; GPIO_PORTD_DATA_R=10
  Stepper_Seek(0,T1ms);// Pos=0; GPIO_PORTD_DATA_R=10
  while(1) {
    Stepper_CW(10*T1ms);   // output every 10ms
  }
}

I thought it could have been that it kept resetting its position and starting again after it reset but even after commenting out the line it wouldn't fix.

Thank you everyone in advance!

gdagis
  • 113
  • 1
  • 4
  • 15
  • Can you post the code that shows how you are using these stepper functions (e.g. where `Stepper_Seek` gets called, etc.)? – DigitalNinja Dec 19 '17 at 21:58
  • add output/debug statements where you are updating `Pos` and compare it to `desired`. Note too that you have a comment `CW steps is 0 to 199` and the next line compares `CWsteps` to 100. Just a red flag...... – KevinDTimm Dec 19 '17 at 22:12
  • The rollover logic is backwards. Pos-- needs to be matched to a check for it reaching 0, Pos++ needs to be checked for reaching 199. – Hans Passant Dec 19 '17 at 22:28

1 Answers1

1

Your wrap-around logic is backward in both Stepper_CW() and Stepper_CCW(). Take the former as the example. Suppose you're trying to reach 198, and Pos is initially 1:

  1. On the first call, Pos is decremented to 0. This is unequal to 198, so the function is called again.
  2. On the second call, Pos is decremented to 199. This is unequal to 198, so the function is called again.
  3. On the third call, the wrap-around case is triggered, and Pos is set to 0. This is unequal to 198 ....

The state after step (3) is the same as the state after step (1) -- infinite loop.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157