Step motor not behaving as planned...

I’ve build an automatic opening/closing hen house hatch (yes really!!) which closes at dusk (photocell) and opens at daybreak, which I’ve had running now for the past 4 weeks, but have an issue which has occurred 3 times now, and for which I’d appreciate your comments.
The code extract below relates to when the hatch opens in the morning, and 7200 cycles of the step motor turns the pulley lifting the hatch until it trips the microswitch. Once tripped, the step motor runs 300 cycles in reverse - lowering the hatch about 10mm.
The purpose of this is to act as a self-adjusting routine, to deal with drive cord stretch, gear jumping etc.
What I am finding is that this routine usually works very well, but on 3 occasions now, the hatch has lifted, tripped the microswitch, but continued to wind up until it reaches 7200 cycles (bending the microswitch arm) and remaining there.
I have confirmed that the microswitch is closing, but for some reason, it’s being ignored, and I can’t work out why??

I’m pretty new to writing code so it could be the way I’ve written it, but I’ve also considered ‘points-bounce’ on the microswitch?

for (i = 0; i <= 7200; i++)  //7200 cycles of step motor = approx 14 revolutions
          {
            vStepMotor(FORWARD);  //Tells the step motor to run through one cycle
            if (digitalRead(microswitch_pin) == LOW) {
              delay (50);
                for (j = 0; j <= 300; j++) //300 cycles of step motor = approx 1/2 revolution
                  {
                  vStepMotor(REVERSE);  //Tells the step motor to run one cycle in reverse
                  }
            break; //ends the FORWARD loop
     }
}

I very strongly suspect that the switch is not causing a "low" that is detectable by your code. Or something else is causing electrical interference. (Chicken s--t?).

If I was relying on the switch to identify the limit of travel I wouldn't bother with a fixed number of steps - I would just step until the switch is triggered. However that has nothing to do with your problem.

I presume the switch should stay low so that it could be detected on several loops?

How is it wired up? Are you using INPUT_PULLUP?

...R

I very strongly suspect that the switch is not causing a "low" that is detectable by your code. Or something else is causing electrical interference. (Chicken s--t?). It's well contained in a Chicken s--t free zone!

If I was relying on the switch to identify the limit of travel I wouldn't bother with a fixed number of steps - I would just step until the switch is triggered. However that has nothing to do with your problem. The limit of travel was set such that no damage would be caused if (as in this case) the system failed, it just bends the microswitch arm instead of damaging the motor - or snapping the drive cord.

I presume the switch should stay low so that it could be detected on several loops? Yes, once the microswitch trips, it remains low until the microswitch arm lowers.

How is it wired up? Are you using INPUT_PULLUP? Again, yes. It's normally high, and if trips - goes low.

Does that break work as you expect it to?

You could choose to set i to 7200 instead of doing that break. That should get you the same result of ending the forward loop.

You could choose to set i to 7200 instead of doing that break. That should get you the same result of ending the forward loop. Yes, but the whole purpose on using the microswitch is to keep the system in alignment, to ensure that any cable stretch, gear jumping, etc, can be self correcting. If I simply set it to raise 7200 cycles in the morning, and lower 7200 cycles at night, gradually it would get out of sync, and create slack in the drive cord, or jam the hatch up against the pulley.

I mean:

for (i = 0; i <= 7200; i++)  //7200 cycles of step motor = approx 14 revolutions
          {
            vStepMotor(FORWARD);  //Tells the step motor to run through one cycle
            if (digitalRead(microswitch_pin) == LOW) {
              delay (50);
                for (j = 0; j <= 300; j++) //300 cycles of step motor = approx 1/2 revolution
                  {
                  vStepMotor(REVERSE);  //Tells the step motor to run one cycle in reverse
                  }
            i = 7200; //ends the FORWARD loop
     }
}

It’s different, but with the same result.

MAS3 - The break command seems to work OK, but by trying to isolate the problem (by inserting error checking code) it appears that for some reason, the line; if (digitalRead(microswitch_pin) == LOW) {.......... ....is not being acted upon, so we don't even get as far as the break. Also, why does it run as intended 90% of the time, but then throw a wobbly?

Everything seems to work but detection LOW in that (GRRR*!) pin. ? defective I/O pin - try switch to other pin. Solder joints one again ? (as there isnt obvious errors in your code)

knut_ny: Everything seems to work but detection LOW in that (GRRR*!) pin. ? defective I/O pin - try switch to other pin. Solder joints one again ? (as there isnt obvious errors in your code)

That's really what I wanted to hear, as I'm not very confident with coding. If the code appears OK, I'll pull the panel out and re-do the physical connections.

Thanks all

Paul

How is your decoupling? http://www.thebox.myzen.co.uk/Tutorial/De-coupling.html

Grumpy_Mike: How is your decoupling? http://www.thebox.myzen.co.uk/Tutorial/De-coupling.html

I did suspect this (first post - points-bounce), but surprised that the; delay (50); didn't deal with the contact noise/change of state. Would you recommend putting a 0.1uF cap across the contacts, or from gnd to microswitch pin?

No, decoupling is nothing to do with contact bounce. It is to suppress voltage variations on the power supply these can be caused by your motor and they make the whole system unreliable which is the situation you have.

pauldreed: I very strongly suspect that the switch is not causing a "low" that is detectable by your code. Or something else is causing electrical interference. (Chicken s--t?). It's well contained in a Chicken s--t free zone!

I think you missed the important point of my comment - the switch not working as you think.

The Chicken s--t was my attempt at a joke.

...R

Grumpy_Mike: No, decoupling is nothing to do with contact bounce. It is to suppress voltage variations on the power supply these can be caused by your motor and they make the whole system unreliable which is the situation you have.

I opted for a separate power supply for the step motor which keeps the heavy drain away from the Processor, but I suppose the same thing could occur with the motor driver which shares the same power supply. I have got some decoupling, although absolute minimal at the moment. I'll read up some more on decoupling, and beef it up, also checking the physical connections (again). Thanks all

Paul

MAS3:
I mean:

for (i = 0; i <= 7200; i++)  //7200 cycles of step motor = approx 14 revolutions

{
            vStepMotor(FORWARD);  //Tells the step motor to run through one cycle
            if (digitalRead(microswitch_pin) == LOW) {
              delay (50);
                for (j = 0; j <= 300; j++) //300 cycles of step motor = approx 1/2 revolution
                  {
                  vStepMotor(REVERSE);  //Tells the step motor to run one cycle in reverse
                  }
            i = 7200; //ends the FORWARD loop
     }
}




It's different, but with the same result.

Actually not quite the same result as a “break;”. After stepping back 300 cycles the motor will step forward once more as the first line of the loop is “for (i = 0; i <= 7200; i++)”. To prevent that happening the last line in the loop should be “i = 7201; //ends the FORWARD loop”.

are U sure? I'd beleive 7200 will be just fine! (use it myself if i didnt couldnt fint the break)

Knut_ny, I think that gm1mfn is correct, because the test is ‘i <= 7200’, and if you set ‘i = 7200;’ then the FORWARD condition will be met and run through 1 more cycle.
It would be different if the test was ‘i < 7200’ of course.

The attached schematic, which is just the minimal components to support the Atmega 328 is how I’ve built the panel.
I’m using 4 of the digital pins to drive the ULN2003 driver board, 1 to monitor the microswitch, 1 to power a LDR, an analogue pin for reading the LDR, and a few more pins for a indicator/fault LED, and over-ride manual switches.
The 0.1uF caps are very close to the chips and I have kept their legs short. Are these sufficient?

Paul

paulreed 7200 has exacly sam effect as break in this case. Ther will be no "extra turn"

This is a very interesting discussion.

But I have seen nothing to suggest that it has been proved that the problem not due to a faulty switch or faulty wiring to the switch.

...R

Robin2: But I have seen nothing to suggest that it has been proved that the problem not due to a faulty switch or faulty wiring to the switch.

...R

I totally agree Robin, but I want to cover all feasible options before dismantling the hatch and removing the pcb (because removing it is a pain!). Once it's disassembled, I can check all of the connections/wiring, replace the switch, and if additional decoupling is required then that can be added too. I don't want to have to keep removing/refitting the PCB if I can help it, so I'm happy to take all of the advice on board, and not just go with 'the most likely' suspect.

Paul