Bug in code that causes engine to start running after 30 seconds of inactivity --> Arduino Step Motor with one push button 90° CW, Same button 90°CCW

seems that you need something that works reliably first.

the modulo operation can be done within step(), a target set and the motor stepped until pos equals target, moving either +/- depending on where the target is, +/- relative to pos

that's correct, it has no influence.
Only without it, I still have the bug

to be sure the button is not actif

that's my button, i tap the GND against 3..
I cannot use the real setup yet :smiling_face:

this is the last code with 1 button, it works, but after 30s inactivity the engine start to spin

int Pin1 = 8;//IN1 is connected to 8 
int Pin2 = 9;//IN2 is connected to 9  
int Pin3 = 10;//IN3 is connected to 10  
int Pin4 = 11;//IN4 is connected to 11 
int switchCWCCW   =3;//define input pin for CW/CCW push button

bool direction_CW=true;

int speedFactor =1;//1=fastest, 2=slower or 3 more slower
long goToAngle = 90;

int correction_CW = 150;//watch video for details
int correction_CCW = 150;//watch video for details

const int CW =1;
const int CCW =2;
const int STOP =3;
int poleStep = 0; 
long stepVale =0;
const int SPR=64*64;

int pole1[] ={0,0,0,0, 0,1,1,1, 0};//pole1, 8 step values
int pole2[] ={0,0,0,1, 1,1,0,0, 0};//pole2, 8 step values
int pole3[] ={0,1,1,1, 0,0,0,0, 0};//pole3, 8 step values
int pole4[] ={1,1,0,0, 0,0,0,1, 0};//pole4, 8 step values

int count=0;
int  dirStatus = STOP;// stores direction status 3= stop (do not change)

void setup() 
{ 
  //Robojax.com Stepper Push button Any Angle STPB-4
  Serial.begin(9600);
  Serial.begin("Robojax Video for Stepper Motor STPB-2");  
 pinMode(Pin1, OUTPUT);//define pin for ULN2003 in1 
 pinMode(Pin2, OUTPUT);//define pin for ULN2003 in2   
 pinMode(Pin3, OUTPUT);//define pin for ULN2003 in3   
 pinMode(Pin4, OUTPUT);//define pin for ULN2003 in4   

 pinMode(switchCWCCW,INPUT_PULLUP);
  
} 
 void loop() 
{ 
    stepVale = (SPR * goToAngle)/360 ;
  //Robojax.com Stepper Push button Any Angle STPB-4
  if(digitalRead(switchCWCCW) == LOW) 
  {
    if (dirStatus == CW) {
      dirStatus = CCW;
      direction_CW = false;
    }
    else {
      dirStatus = CW;
      direction_CW=true;
    }
    count =0;
    delay(200);
  }
  
 if(dirStatus ==CCW){ 
   poleStep++; 
   count++;   
   if(count+correction_CCW <= stepVale)
   {
    driveStepper(poleStep);      
   }else{
      driveStepper(8);  
   }
  
 }else if(dirStatus ==CW){ 
   poleStep--; 
   count++;   
   if(count+correction_CW <=stepVale)
   {
    driveStepper(poleStep);      
   }else{
      driveStepper(8);  
   }   
 }else{
  driveStepper(8);   
 }
 if(poleStep>7){ 
   poleStep=0;
 } 
 if(poleStep<0){ 
   poleStep=7; 
 } 
 delay(speedFactor); 
  
}// loop


void driveStepper(int c)
{
      digitalWrite(Pin1, pole1[c]);  
     digitalWrite(Pin2, pole2[c]); 
     digitalWrite(Pin3, pole3[c]); 
     digitalWrite(Pin4, pole4[c]);
     
}//driveStepper ends here

you may stop stepping when your count > stepVale, but count continues to be incremented and will wrap at 65535 and become < stepVale again

2 Likes

That won't do anything. As long as the button pin is pulled LOW by touching your bare wire to GND, it'll remain low even if you write the (input!) pin as HIGH. And if the wire doesn't touch anything, the internal pullup resistor will force the pin HIGH anyway. So it's a redundant line of code.

the above allow poleStep to become -1 and 8, which are outside the "proper" range of

poleStep %= 8; would limit it

These are lines that come from the working program with 3 buttons (CW/CCW/STOP), only after the transition to one button did the bug arise

if(digitalRead(switchCCW) == LOW) 
  {
    dirStatus =CCW;
    count =0;
  }else if(digitalRead(switchCW) == LOW)
  {
   dirStatus  = CW;  
    count =0;   
  }
  if(digitalRead(switchSTOP) == LOW)
  {
    dirStatus  = STOP;
    delay(200);

add this and see for yourself

void driveStepper(int c)
{
    static int c0;

    if (c0 != c) {
        char s [90];
        sprintf (s, "c %2d, poleStep %2d, count %5d, stepVale %3ld, dirSta %2d dirCw %2d",
        c, poleStep, count, stepVale, dirStatus, direction_CW);
        Serial.println (s);
    }
    c0 = c;

    digitalWrite(Pin1, pole1[c]);
    digitalWrite(Pin2, pole2[c]);
    digitalWrite(Pin3, pole3[c]);
    digitalWrite(Pin4, pole4[c]);

}

good luck

thanks, but doesn't work, the stepper goes very verry slow now (the leds blink also very long one for one).

the prints are slowing things down. try 115200 instead of 9600

I didn't think this would be such a difficult program, 1 button turns a motor CW and CCW to a set angle...

Yes, I looked for that, but didn't find one with 1 push button and adjustable angle.
it always concerns 1 button CW and 1 CCW

#define MyHW
#ifdef MyHW
const byte PinStepper [] = { 10, 11, 12, 13 };
const byte PinButs    [] = { A1, A2, A3 };

int speedFactor = 250;

#else
const byte PinStepper [] = { 8, 9, 10, 11 };
const byte PinButs    [] = { 2, 3, 4 };

int speedFactor = 1;//1=fastest, 2=slower or 3 more slower
#endif

enum { ButStop, ButP0, ButP1 };

const int Nbut = sizeof(PinButs);
byte      butState [Nbut];;

const int Npole = sizeof(PinStepper);

const byte pole [][8] = {
     { 0,0,0,0, 0,1,1,1 },
     { 0,0,0,1, 1,1,0,0 },
     { 0,1,1,1, 0,0,0,0 },
     { 1,1,0,0, 0,0,0,1 },
};

unsigned targ;
unsigned pos;
int      dir;

// -----------------------------------------------------------------------------
void step (
    unsigned c)
{
    Serial.println (c);

    c %= Npole;
    for (int n = 0; n < Npole; n++)
        digitalWrite (PinStepper [n], pole [n][c]);
}

// -----------------------------------------------------------------------------
void loop ()
{
    // handle button
    for (int n = 0; n < Nbut; n++)  {
        byte but = digitalRead (PinButs [n]);
        if (butState [n] != but) {      // change
            butState [n] = but; 
            delay (20);                 // debounce

            if (LOW == but)  {          // pressed
                switch (n)  {
                case ButStop:
                    targ = pos;
                    break;

                case ButP0:
                    targ = 0;
                    break;

                case ButP1:
                    targ = 10;
                    break;
                }
            }
        }
    }

    // step
    if (targ != pos)  {
        if (pos < targ)
            pos++;
        else if (pos > targ)
            pos--;

        step (pos);
        delay (speedFactor);
    }
}

// -----------------------------------------------------------------------------
void setup ()
{
    Serial.begin (9600);

    for (int n = 0; n < Npole; n++)
        pinMode (PinStepper [n], OUTPUT);

    for (int n = 0; n < Nbut; n++)  {
        pinMode (PinButs [n], INPUT_PULLUP);
        butState [n] = digitalRead (PinButs [n]);
    }
}

thanks for that, If I loud that, nothing happen...
Do I have to change first something?

Yes, it is. Yes, they are.

What is you food budget? You buy a weeks worth of goods, and complain to every passing stranger that they are not cooking your meals for you?

I thought I wrote this before... Disconnect power to your driver-board. Does it shake?

1 Like

Nice, that's right, it's actually 32 seconds... you found the bug!
However, I have already understood that I do not need to be on this forum for the one on one solution, which I respect.
Thanks again everyone for their valuable time

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.