Find the bug!!!

Hello everybody i’m working with a project. i will really appreciate some help here

components
one button
one stepper and driver
one optocoupler --to get the home position of the motor

How it work
run calibratin of motor
wait for user to push
push the button----mov the motor to a position out of 6
wait for timer to finish
return to home position
wait for user to push again

//-----------------------T H E B U G-------------

Most of the time works perfect but sometimes when button is pushed the program belive the timer is finish and send the motor home at once…

This happen most frequently after the button is used at least once…
can any of u guys spot the flaw in the code(messy code)

PLEASE HELP!!!..

#include <Stepper.h>

const int stepsPerRevolution = 2038;  // change this to fit the number of steps per revolution
// for your motor
int wheelPos (6);//Joel
int LastwheelPos;//Joel
int lastmotorposition;
int opto = 7; //optointeruptor
// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11);
int count;
int stepCount = 0;  // number of steps the motor has taken
int button= 12; //input from panel
int limit = digitalRead(opto); // optointeruptor reading
bool button_state; //input state of panel
unsigned long currentMillis = millis(); // grab current time
unsigned long previousMillis = millis(); // millis() returns an unsigned long.
unsigned long pause = ( 10 * 1000UL); //(24* 60 * 60 * 1000UL); //time to wait in color change
unsigned long testMillis = 0;
int timer_state = 0;
int last_timer_state = 0;
int ledPins[] = {
  A0, A1, A2, A3, A4, A5
};
int pinCount = 6;
int mov = 339.6; //pasos a mover hasta la  pocicion standars


//---------------------------------------------------------S E T U P-----------------------------------------------
void setup() {



  myStepper.setSpeed(10);
  Serial.begin(57600);

  pinMode(button, INPUT_PULLUP);
  pinMode(opto, INPUT);



  for (int thisPin = 0; thisPin < pinCount; thisPin++) {
    pinMode(ledPins[thisPin], OUTPUT);
  }
  Serial.println("v4");
  printcode();
  //-------------------------motor warm up--------------------------
  motor_warm_up();
  //----------------------------positioning-------------------------
  motor_positioning();



  ///-------------------------------
  motor_sleep();// sleep stepper

  ///-------------------------------LYS TEST----------
  lystest();
  ///-------------------------------
  Serial.println("END of setup");
  //----------------------------END of positioning-------------------------
}


void loop() {
  //----------------------------------------------------------------------------------------------------
  //--------------------------------------  L   O    O   P   -----------------------------------------
  //----------------------------------------------------------------------------------------------------



  button_state = digitalRead(button); //read buttonpresed panel

  if (button_state == 0) {
    debouncer(); //buttondebouncer
  }

  if (button_state  == 0 && wheelPos <= 5 ) { //  If boton is push
    wheelPos ++;
    //-----------------------------------PANEL LED ---------------------------------

    ledpanellys(wheelPos); //lights in buttonpanel

    Serial.println("boton precionado");
    Serial.println(wheelPos);

    myStepper.step(mov);// -------------------------- mov to mnext pos-----------------------



    delay(20);
  }
  //------------------------------correction to 0----------------------
  motor_return_home();

  //---------------------- starting counting ---------------------

  if (wheelPos  < 6 && wheelPos > 0 ) {


    if (timer_state == 0) previousMillis = millis();

    Serial.print   (last_timer_state);//debuging
    Serial.println (timer_state);   //debuging

    unsigned long currentMillis = millis(); // grab current time
    if ((unsigned long)(currentMillis - previousMillis) >= pause) {


      Serial.println("pausa");//debuging
      Serial.println(currentMillis - previousMillis);//debuging
      Serial.println("previousMillis");//debuging
      Serial.println(previousMillis);//debuging
      Serial.println("countdown finish"); //debuging
      Serial.println(wheelPos); //debuging

      motor_return(); //go home and set wheelps to 0
      last_timer_state = 1; //timer finish



      delay (5);

    }
    if (last_timer_state == 1) {
      last_timer_state = 0;
      timer_state = 0;
    } else {
      timer_state = 1;
    }

    delay (5);


  }

  //--------------------------------------------------------------
  if (wheelPos  == 6) {
    wheelPos = 0;

  }
  motor_sleep();
  delay(15);

}



// ----------------------------------------end of LOOP-------------------------------------------------------------
void motor_return_home() {
  limit = digitalRead(opto);
  while (limit == 1 &&  wheelPos == 6) {
    limit = digitalRead(opto);
    myStepper.step(1);
    delay(1);

  }
}
void motor_positioning() {
  while (limit == 1) {
    limit = digitalRead(opto);
    myStepper.step(-1);
    Serial.println("positioning");
  }
}
void motor_warm_up() {
  for (int i = 0; i < 4; i++) {
    myStepper.step(-50);
    limit = digitalRead(opto);
    Serial.println(limit);
    Serial.println("motor warm ");
    //delay(15);
  }
}
void motor_return() {
  limit = digitalRead(opto);
  while (limit == 1 &&  wheelPos != 6) {
    limit = digitalRead(opto);
    myStepper.step(-1);

  }
  LED_OFF();
  digitalWrite(ledPins[5], 1);
  wheelPos = 0;
}
void LED_OFF() {

  for (int thisPin = 0; thisPin < pinCount; thisPin++) {
    digitalWrite(ledPins[thisPin], 0);

  }



}
void lystest() {
  for (int thisPin = 0; thisPin < pinCount; thisPin++) {
    digitalWrite(ledPins[thisPin], 1);
    delay (200);

  }

  for (int thisPin = 4; thisPin >= 0; thisPin--) {
    digitalWrite(ledPins[thisPin], 0);
    delay (200);

  }




}
int ledpanellys(int wheelPos1) {
  switch (wheelPos1) {
    case 1:
      LED_OFF();
      digitalWrite(ledPins[0], 1);
      break;
    case 2:
      LED_OFF();
      digitalWrite(ledPins[1], 1);
      break;
    case 3:
      LED_OFF();
      digitalWrite(ledPins[2], 1);
      break;
    case 4:
      LED_OFF();
      digitalWrite(ledPins[3], 1);
      break;

    case 5:
      LED_OFF();
      digitalWrite(ledPins[4], 1);
      break;
    default:
      LED_OFF();
      digitalWrite(ledPins[5], 1);
      break;
  }
}
void debouncer() {
  delay(30);
  button_state = digitalRead(button); //buttonpresed panel//--------------------debouncer----------------
  if (button_state == 0) {
    button_state = 0;
  } else {
    button_state == 1;
  }
}
void motor_sleep() {
  delay(50);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  //Serial.println("-------------------------SLEEP MOTOR------------------------------");
}
void motor_stop() {

  digitalWrite(8, HIGH);
  digitalWrite(9, HIGH);
  digitalWrite(10, HIGH);
  digitalWrite(11, HIGH);
  delay(50);
  //Serial.println("-------------------------STOP------------------------------");
}
void printcode() {

  Serial.println("fredrikstadkommune");
  Serial.println("joel");
}

workingcode_fredrikstad_installert.ino (6.29 KB)

int mov = 339.6;

How many decimal places can an integer hold ?

  if (button_state == 0)
  {
    button_state = 0;
  }
  else
  {
    button_state == 1;
  }

So, if button_state is zero you set it to zero otherwise you compare it to 1 and throw away the answer

I stopped looking when I found these 2 mistakes. Put them right and try the code again

very well spotted, i did fix it and I’m testing it now
I dont manage to se the relationship between those mistake and the bug behavior but i hope they are the one making life difficult :wink:

THANK YOU SO MUCH.

#include <Stepper.h>

const int stepsPerRevolution = 2038;  // change this to fit the number of steps per revolution
// for your motor
int wheelPos (6);//Joel
int LastwheelPos;//Joel
int lastmotorposition;
int opto = 7; //optointeruptor
// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11);
int count;
int stepCount = 0;  // number of steps the motor has taken
int button= 12; //input from panel
int limit = digitalRead(opto); // optointeruptor reading
bool button_state; //input state of panel
unsigned long currentMillis = millis(); // grab current time
unsigned long previousMillis = millis(); // millis() returns an unsigned long.
unsigned long pause = ( 10 * 1000UL); //(24* 60 * 60 * 1000UL); //time to wait in color change
unsigned long testMillis = 0;
int timer_state = 0;
int last_timer_state = 0;
int ledPins[] = {
  A0, A1, A2, A3, A4, A5
};
int pinCount = 6;
int mov = 339; //pasos a mover hasta la  pocicion standars


//---------------------------------------------------------S E T U P-----------------------------------------------
void setup() {



  myStepper.setSpeed(10);
  Serial.begin(57600);

  pinMode(button, INPUT_PULLUP);
  pinMode(opto, INPUT);



  for (int thisPin = 0; thisPin < pinCount; thisPin++) {
    pinMode(ledPins[thisPin], OUTPUT);
  }
  Serial.println("v4");
  printcode();
  //-------------------------motor warm up--------------------------
  motor_warm_up();
  //----------------------------positioning-------------------------
  motor_positioning();



  ///-------------------------------
  motor_sleep();// sleep stepper

  ///-------------------------------LYS TEST----------
  lystest();
  ///-------------------------------
  Serial.println("END of setup");
  //----------------------------END of positioning-------------------------
}


void loop() {
  //----------------------------------------------------------------------------------------------------
  //--------------------------------------  L   O    O   P   -----------------------------------------
  //----------------------------------------------------------------------------------------------------



  button_state = digitalRead(button); //read buttonpresed panel

  if (button_state == 0) {
    debouncer(); //buttondebouncer
  }

  if (button_state  == 0 && wheelPos <= 5 ) { //  If boton is push
    wheelPos ++;
    //-----------------------------------PANEL LED ---------------------------------

    ledpanellys(wheelPos); //lights in buttonpanel

    Serial.println("boton precionado");
    Serial.println(wheelPos);

    myStepper.step(mov);// -------------------------- mov to mnext pos-----------------------



    delay(20);
  }
  //------------------------------correction to 0----------------------
  motor_return_home();

  //---------------------- starting counting ---------------------

  if (wheelPos  < 6 && wheelPos > 0 ) {


    if (timer_state == 0) previousMillis = millis();

    Serial.print   (last_timer_state);//debuging
    Serial.println (timer_state);   //debuging

    unsigned long currentMillis = millis(); // grab current time
    if ((unsigned long)(currentMillis - previousMillis) >= pause) {


      Serial.println("pausa");//debuging
      Serial.println(currentMillis - previousMillis);//debuging
      Serial.println("previousMillis");//debuging
      Serial.println(previousMillis);//debuging
      Serial.println("countdown finish"); //debuging
      Serial.println(wheelPos); //debuging

      motor_return(); //go home and set wheelps to 0
      last_timer_state = 1; //timer finish



      delay (5);

    }
    if (last_timer_state == 1) {
      last_timer_state = 0;
      timer_state = 0;
    } else {
      timer_state = 1;
    }

    delay (5);


  }

  //--------------------------------------------------------------
  if (wheelPos  == 6) {
    wheelPos = 0;

  }
  motor_sleep();
  delay(15);

}



// ----------------------------------------end of LOOP-------------------------------------------------------------
void motor_return_home() {
  limit = digitalRead(opto);
  while (limit == 1 &&  wheelPos == 6) {
    limit = digitalRead(opto);
    myStepper.step(1);
    delay(1);

  }
}
void motor_positioning() {
  while (limit == 1) {
    limit = digitalRead(opto);
    myStepper.step(-1);
    Serial.println("positioning");
  }
}
void motor_warm_up() {
  for (int i = 0; i < 4; i++) {
    myStepper.step(-50);
    limit = digitalRead(opto);
    Serial.println(limit);
    Serial.println("motor warm ");
    //delay(15);
  }
}
void motor_return() {
  limit = digitalRead(opto);
  while (limit == 1 &&  wheelPos != 6) {
    limit = digitalRead(opto);
    myStepper.step(-1);

  }
  LED_OFF();
  digitalWrite(ledPins[5], 1);
  wheelPos = 0;
}
void LED_OFF() {

  for (int thisPin = 0; thisPin < pinCount; thisPin++) {
    digitalWrite(ledPins[thisPin], 0);

  }



}
void lystest() {
  for (int thisPin = 0; thisPin < pinCount; thisPin++) {
    digitalWrite(ledPins[thisPin], 1);
    delay (200);

  }

  for (int thisPin = 4; thisPin >= 0; thisPin--) {
    digitalWrite(ledPins[thisPin], 0);
    delay (200);

  }




}
int ledpanellys(int wheelPos1) {
  switch (wheelPos1) {
    case 1:
      LED_OFF();
      digitalWrite(ledPins[0], 1);
      break;
    case 2:
      LED_OFF();
      digitalWrite(ledPins[1], 1);
      break;
    case 3:
      LED_OFF();
      digitalWrite(ledPins[2], 1);
      break;
    case 4:
      LED_OFF();
      digitalWrite(ledPins[3], 1);
      break;

    case 5:
      LED_OFF();
      digitalWrite(ledPins[4], 1);
      break;
    default:
      LED_OFF();
      digitalWrite(ledPins[5], 1);
      break;
  }
}
void debouncer() {
  delay(30);
  button_state = digitalRead(button); //buttonpresed panel//--------------------debouncer----------------
  if (button_state == 0) {
    button_state = 0;
  } else {
    button_state = 1;
  }
}
void motor_sleep() {
  delay(50);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  //Serial.println("-------------------------SLEEP MOTOR------------------------------");
}
void motor_stop() {

  digitalWrite(8, HIGH);
  digitalWrite(9, HIGH);
  digitalWrite(10, HIGH);
  digitalWrite(11, HIGH);
  delay(50);
  //Serial.println("-------------------------STOP------------------------------");
}
void printcode() {

  Serial.println("fredrikstadkommune");
  Serial.println("joel");
}

Unfortunately :frowning: still buggy any other idea?

int ledpanellys(int wheelPos1)

The return value from this function is never used and the function has no 'return' at the end. You should change it to:

void ledpanellys(int wheelPos1)
int wheelPos (6);//Joel

The more traditional way to initialize a variable is:

int wheelPos = 6;//Joel

Are you SURE you want to initialize this value out-of-range?!?

You say that you want this

wait for user to push
push the button----mov the motor to a position out of 6
wait for timer to finish
return to home position

But the code seems to do something different

  if (button_state  == 0 && wheelPos <= 5 )   //  If boton is push
  {
    wheelPos ++;
    //-----------------------------------PANEL LED ---------------------------------
    ledpanellys(wheelPos); //lights in buttonpanel
    Serial.println("boton precionado");
    Serial.println(wheelPos);
    myStepper.step(mov);// -------------------------- mov to mnext pos-----------------------
    delay(20);
  }
  //------------------------------correction to 0----------------------
  motor_return_home();

Why do you call motor_return_home() immediately after moving the motor to another position ?

  if (button_state == 0)
  {
    button_state = 0;
  }
  else
  {
    button_state = 1;
  }

You have corrected this portion of code but it is a waste of time as the value of button_state is not changed anyway

thank you John
i see you there is no need for the int thank you
the initial position is important due to fact that that's the standby position

thank you UKHeliBob

i see the redundancy in that part of the code

if (button_state == 0)
  {
    button_state = 0;
  }
  else
  {
    button_state = 1;
  }

the return home is used as the last position (6) since the last and first position are the same in this way i assure that is exactly at the same home spot with the use of the opto sensor

the return home is used as the last position (6) since the last and first position are the same

Why do you call motor_return_home() unconditionally in loop() whatever the value of wheelPos immediately after moving the motor to its position ?

that only happens if the wheel position is 6 means the 360 degres have been move
is a color wheel with 6 colors one standby and you move to next color by pushing the button and if you push 6 times you are back home .. thats the idea
inside the return home you get this while

limit = digitalRead(opto);
  while (limit == 1 &&  wheelPos == 6) {
    limit = digitalRead(opto);
    myStepper.step(1);
    delay(1);

Here is a picture

that only happens if the wheel position is 6

That is not how I read this portion of the loop() function

void loop()
{
  //----------------------------------------------------------------------------------------------------
  //--------------------------------------  L   O    O   P   -----------------------------------------
  //----------------------------------------------------------------------------------------------------
  button_state = digitalRead(button); //read buttonpresed panel
  if (button_state == 0)
  {
    debouncer(); //buttondebouncer
  }
  if (button_state  == 0 && wheelPos <= 5 )   //  If boton is push
  {
    wheelPos ++;
    //-----------------------------------PANEL LED ---------------------------------
    ledpanellys(wheelPos); //lights in buttonpanel
    Serial.println("boton precionado");
    Serial.println(wheelPos);
    myStepper.step(mov);// -------------------------- mov to mnext pos-----------------------
    delay(20);
  }
  //------------------------------correction to 0----------------------
  motor_return_home();

Note that the call to motor_return_home() is unconditional and that it will happen each time through loop()

I am quite prepared to believe that I am wrong, but I can’t currently see where or how. Can you please clarify how motor_return_home() is only called when wheelPos equals 6 ?

Thank u guys for taking this challenge så fast

every time the code get there in the loop
it will read de position sensor for 1 means not trigger an for wheelPos to be 6
while this is true will than move the stepper one step at the time until home is reached.
the conditional is inside the function.. may not be e best practice

this is the function itself

void motor_return_home() {
  limit = digitalRead(opto);
  while (limit == 1 &&  wheelPos == 6) {
    limit = digitalRead(opto);
    myStepper.step(1);
    delay(1);

  }
}

Silly old me for thinking for one second that a function named motor_return_home() returned the motor to its home position

I got the hint :slight_smile: and put it inside an if statement , i belive i found the reason but im not sure

I think that since the counter start at once you push the button an you move it all the way pass home while looking for the position may interfere with the millis and use and old last millis as a consequence the
equation current millis - lastmillis > pause will be TRUE and will execute

now i'm trying to make it wait for 10 sec of inactivity after button pushed to confirm position selection.

or do you guys have a better idea?

I got the hint :slight_smile: and put it inside an if statement ,

That sounds much more sensible

now i'm trying to make it wait for 10 sec of inactivity after button pushed to confirm position selection.

or do you guys have a better idea?

It would be better if the code detected when the button becomes pressed rather than when it is pressed. Have a look at state change detection tutorial