Stepper homing program not changing state

Hello Everyone, I have a working sketch which uses a stepper to drive a filter wheel to any one of four positions inputted by serial command. As it is now, I have to manually set a starting position each time the project is powered on. I would like to have the wheel drive at power-up until a magnet reaches a reed switch and then stop. Before altering the code I have so far, I have a separate sketch which I am including here in its entirety. Once I have this homing to a zero position, I will include this in the code.
The Nano is powered through the USB, while the driver board is powered by a 5v regulator. All grounds are common. As it is now, when the circuit is powered up, it drives the wheel, reporting to the serial monitor:
“0” (state of interrupt pin)
“4093” (steps taken per cycle)
“cycle count=n” (number of cycles attempted)
But the program never recognizes the change of state when I change digital pin 2 to low by switching it to ground. So there is something in the code I have not set up right and can’t seem to figure it out. I tried using another Nano just in case I may have damaged something in the experimenting.

[code]
#include <AccelStepper.h>  
#define HALFSTEP 8  
#define motorPin1  8     // IN1 on ULN2003 ==> Blue   on 28BYJ-48  
#define motorPin2  9     // IN2 on ULN2004 ==> Pink   on 28BYJ-48  
#define motorPin3  10    // IN3 on ULN2003 ==> Yellow on 28BYJ-48  
#define motorPin4  11    // IN4 on ULN2003 ==> Orange on 28BYJ-48  
int endPoint = 4096;     // Move this many steps, approx one full turn  
AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);  
volatile boolean stopNow = false;    // flag for Interrupt Service routine  
int cycleCount = 0;                  // counter for endpoint cycles  
boolean homed = false;               // flag to indicate when motor is homed  
void setup()  
{  
  attachInterrupt(2, intService, LOW);           // Enable interrupt D2, switch pulled low  
  Serial.begin(9600);  
  Serial.println(stepper1.currentPosition());  
  delay(5000);  
  
  stepper1.setMaxSpeed(1000.0);  
  stepper1.setAcceleration(200.0);  
  stepper1.setSpeed(400);  
  stepper1.moveTo(endPoint);  
}  
void loop()  
{  
  if (stopNow)  
   {  
     detachInterrupt(0);                          // Interrupt not needed again (for the moment)  
     Serial.print("Interrupted at ");  
     Serial.println(stepper1.currentPosition());  
     stepper1.stop();  
     stepper1.setCurrentPosition(0);  
     Serial.print("position established at home...");  
     Serial.println(stepper1.currentPosition());  
     stopNow = false;                            // Prevents repeated execution of the above code  
     homed = true;  
   }  
  else  
  if (stepper1.distanceToGo() == 0 && !homed)     //executed repeatedly until we hit the limitswitch  
   {  
     Serial.println(stepper1.currentPosition());  
     stepper1.setCurrentPosition(0);  
     stepper1.moveTo(endPoint);  
     cycleCount ++;  
     Serial.print("cycle count = ");  
     Serial.println(cycleCount);  
     Serial.println(stepper1.currentPosition());  
   }  
  stepper1.run();  
  if(homed)  
   {  
     Serial.println("I am homed");
   }  
}   
void intService()  
{  
  stopNow = true; // Set flag to show Interrupt recognised and then stop the motor  
}

[/code]

while all I/O pins are input by default, do you need to configure that pin with a pullup

pinMode (2, INPUT_PULLUP);

and you might consider using digitalPinToInterrupt(pin). See attachInterrupt()

i've never understood the distinction in hardware detecting a FALLING vs LOW state. Not sure if a persistent LOW condition immediately retriggers an interrupt once it completes. You might consider FALLING.

You really don’t need an interrupt for this. Where you check for stopNow just check for a HIGH to LOW state change on that digital input.

Thanks to both of you for replying. I've tried to implement the suggestions by using a digitalPinToInterrupt and commenting out the attachinterrupt and intService statements. Now it thinks it is already in home position. Motor does not turn, and monitor report "I am Homed". I tried using the article in Arduino Interrupts Tutorial with Example Interrupt Demonstration, but I'm just getting it all goofed up.

[code]
#include <AccelStepper.h>  
#define HALFSTEP 8  
#define motorPin1  8     // IN1 on ULN2003 ==> Blue   on 28BYJ-48  
#define motorPin2  9     // IN2 on ULN2004 ==> Pink   on 28BYJ-48  
#define motorPin3  10    // IN3 on ULN2003 ==> Yellow on 28BYJ-48  
#define motorPin4  11    // IN4 on ULN2003 ==> Orange on 28BYJ-48  
int endPoint = 4096;     // Move this many steps, approx one full turn  
AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);  
volatile boolean stopNow = false;    // flag for Interrupt Service routine 
volatile int output = LOW; 
int cycleCount = 0;                  // counter for endpoint cycles  
boolean homed = false;               // flag to indicate when motor is homed  
void setup()  
{  
  //attachInterrupt(2, intService, LOW);           // Enable interrupt D2, switch pulled low 
  attachInterrupt(digitalPinToInterrupt(2),Switch, HIGH);
  pinMode (2, INPUT); 
  Serial.begin(9600);  
  Serial.println(stepper1.currentPosition());  
  delay(5000);  
  
  stepper1.setMaxSpeed(1000.0);  
  stepper1.setAcceleration(200.0);  
  stepper1.setSpeed(400);  
  stepper1.moveTo(endPoint);  
}  
void loop()  
{  
  if (stopNow)
   {  
     detachInterrupt(0);                          // Interrupt not needed again (for the moment)  
     Serial.print("Interrupted at ");  
     Serial.println(stepper1.currentPosition());  
     stepper1.stop();  
     stepper1.setCurrentPosition(0);  
     Serial.print("position established at home...");  
     Serial.println(stepper1.currentPosition());  
     stopNow = false;                            // Prevents repeated execution of the above code  
     homed = true;  
   }  
  else  
  if (stepper1.distanceToGo() == 0 && !homed)     //executed repeatedly until we hit the limitswitch  
   {  
     Serial.println(stepper1.currentPosition());  
     stepper1.setCurrentPosition(0);  
     stepper1.moveTo(endPoint);  
     cycleCount ++;  
     Serial.print("cycle count = ");  
     Serial.println(cycleCount);  
     Serial.println(stepper1.currentPosition());  
   }  
  stepper1.run();  
  if(homed)  
   {  
     Serial.println("I am homed");
   }  
}   
void Switch()

//void intService()  
{  
  stopNow = true; // Set flag to show Interrupt recognised and then stop the motor  
}

[/code]

The simplest way to home a stepper is to move one step at a time and check the limit switch between steps.

...R

Hello bsturges,

there seems to be a beginners habit of coding plenty of lines before testing.
But you are on the right way with your testing code.
To narrow down the problem I suggest to check smaller things.
Checking if the interrupt really works.

Depending on your hardware not every pin can be configured for initiating interrupts.

here is a democode that I used to check if the interrupt works at all

struct Button {
  const uint8_t PIN;
  uint32_t numberKeyPresses;
  bool pressed;
};

Button button1 = {18, 0, false};

// set IRAM attribute to place the ISR-code into Internal RAM
// which makes execution as fast as possible

void IRAM_ATTR isr() {   
  button1.numberKeyPresses += 1;
  button1.pressed = true;
}

void setup() {
  Serial.begin(115200);
  pinMode(button1.PIN, INPUT_PULLUP);
  attachInterrupt(button1.PIN, isr, FALLING);
}

void loop() {
  if (button1.pressed) {
      Serial.printf("Button 1 has been pressed %u times\n", button1.numberKeyPresses);
      button1.pressed = false;
  }

  //Detach Interrupt after 1 Minute
  static uint32_t lastMillis = 0;
  if (millis() - lastMillis > 60000) {
    lastMillis = millis();
    detachInterrupt(button1.PIN);
  Serial.println("Interrupt Detached!");
  }
}

Next step would be making the stepper just turning around endlessly
increment a counter inside your interrup-service-routine (in short ISR) each time the ISR is called.
printout the value o fthis counter every second to see if the counter moves up while the magnet switches the read-contact.

another question what kind of electronic equipment do you have for checking?

Lately I had a strange problem that my code should measure a frequency of 0-50 Hz but it did not work correctly. It turned out that the optokoppler I was using produced a voltage of around half of the supply-voltage. I only found this by hanging up my oscilloscope to the input-pin.
Code was fine, circuitry was (almost) fine and still it did'nt worked.

So at least you should check with a digital multimeter if the voltage alternates between supply-voltage and zero if you switch the reed-contact with a magnet by hand or by hand-turning your wheel.

best regards

Stefan
best regards

Stefan