Looking for help on why randomly moving without any signal

I have this Arduino code to open and close some blinds using a stepper motor. I thought I solved it when I came upon description of common errors with switches,

I put a resister between positive and pin D2. I even tried one in the negative position and I still get "random switching of the blinds"
I have not created the code myself I have pieced it together from different locations. I am trying to learn as I go.
Just without notice the blinds move open or closed randomly throughout the day.
Some basic trouble shooting I have done is...
Completely remove the Remotec ZFM-80 from the scenario. - Still get random movement
But in different size resistors. 22 1/2 volt 10 1 volt. - Still get random movement
Replace the ULN2002 - still get random movement
Currently power from usb. I tried putting power directly to motor and keep usb power. = still get random movement

When I say random movement I mean it does the whole stepper.move(-8192) or stepper.move(8192) taking place but just when it wants to move and if I signal it to move.

When connected everything works when I hit the button. (blinds turn) Hit button again blinds turn other way. It is just the random turning that has me baffled. I have attach wiring layout and code using
Looking for some other suggestions.

Thank you,
Dave

allies_room_blind.ino (1.34 KB)

sketch.pdf (132 KB)

void setup()
{
  cli();
  stepper.setPeriod(5);
  pinMode(ITR_PIN, INPUT_PULLUP);
  attachInterrupt(0, buttonPressed, FALLING);
  sei();
}

Nothing you are doing there requires disabling interrupts. So, stop doing it.

volatile boolean forward = false;
volatile boolean start = false;
volatile boolean first = true;

First what? Start what?

Why are you using interrupts at all? 99.9% of the time, that code is doing nothing. Interrupts are for things that need to be handled right now, like arriving serial data. I find it difficult to believe that a 5 nanosecond delay between pressing the switch and the blinds starting to open or close is going to be that big a deal.

I am under the impression that I need the following for the Boolean logic to work

volatile boolean forward = false;
volatile boolean start = false;
volatile boolean first = true;

Those I thought are use to change the state of the program based on if the button has been push.
I thought they are needed for the following statements to work; since those are the variable I call in each phase.

void buttonPressed()
{
  if (!first)
  {
    if (!start)
    {
      forward = !forward;
      start = true;
    }
  }
  else
  {
    first = false;
  }
}

void setup()
{
  
}

void loop()
{
  if (start)
  {
    if (forward)
    {
      stepper.move(8192);  //allines close
      stepper.stop();
    }
    else
    {
      stepper.move(-8192);   //Allines open
      stepper.stop();
    }
    start = false;
  }
}

The other stuff you have stated for me to remove. That is fine but do i still leave
void Setup () {
}
?

I am under the impression that I need the following for the Boolean logic to work

You do, but it's logic only if it makes sense. start and first do not, because there is no clue what is starting or what the first event is. You need better names.

The other stuff you have stated for me to remove. That is fine but do i still leave
void Setup () {
}
?

You only need to remove the calls to cli() and sei().

You have not explained why you are using an interrupt (take note of the fact that the blinds need to be closed immediately) when polling the switch seems like it should be fast enough, given that checking the digital pin hardly takes longer than checking the boolean.

(I know that digitalRead() takes time, so don't jump all over me for this statement; however, the sketch is doing nothing else, so the time that it takes is hardly material.)

Trust me I am not going to jump over anybody. I am just grateful for another set of eyes to help me. (Wife is a bit upset that blinds are moving all over)

I guess I am under the impression that an interrupt is used to signal a change in the state of either pin 2 or 3. Thus, I am needing to read the state change in pin 2. So when I push the button it changes the state of pin 2 in my case thus utilizing an interrupt to read pin 2.

// Intderruption on PIN2, push-button connected to pull-up
#define ITR_PIN 2
#define ITR_NB 0
pinMode(ITR_PIN, INPUT_PULLUP);
  attachInterrupt(0, buttonPressed, FALLING);

But I guess this is not needed? I am not understanding the correct use of an interrupt?

datammwv:
Trust me I am not going to jump over anybody. I am just grateful for another set of eyes to help me. (Wife is a bit upset that blinds are moving all over)

I guess I am under the impression that an interrupt is used to signal a change in the state of either pin 2 or 3. Thus, I am needing to read the state change in pin 2. So when I push the button it changes the state of pin 2 in my case thus utilizing an interrupt to read pin 2.

Look up 'finite state machine'.
Your blinds have four states:

  1. blinds closed...Digitalread (button pin)
  2. blinds opening
  3. blinds open...Digitalread (button pin)
  4. blinds closing
    then back to state 1...

The Arduino runs very quickly and the need for blind movement is very slow so that you can detect the occasional button press using digitalRead() with a lot less programming complication than using interrupts.

Interrupts are best kept for things that need a response within a few microseconds or when you need to detect very short duration pulses. A button press is a long duration pulse by Arduino standards.

My guess is that your interrupts are responding to electrical noise when the blinds move without the button being pressed. It's much easier to debounce buttons when you are just using digitalRead().

...R

So if I am looking at a finite state example
Look up 'finite state machine'.
Your blinds have four states:

  1. blinds closed...Digitalread (button pin) = static state = stepper.stop();
  2. blinds opening = Transitional state = stepper.move(8192);
  3. blinds open...Digitalread (button pin) = static state = stepper.stop();
  4. blinds closing =transitional state = = stepper.move(-8192);
    then back to state 1...

I would include this also.

#include <StepperMotor.h>

// 4 pins of the stepper motor board
#define _PIN1 11
#define _PIN2 10
#define _PIN3 9
#define _PIN4 8
StepperMotor stepper(_PIN1, _PIN2, _PIN3, _PIN4);

I guess this where I get stuck on the actual code to follow for finite state machine?

Hi, can we please have a picture of your project and a CAD or picture of a hand drawn circuit diagram.
What are you using to power the arduino, also what model arduino?
What are you using to power the motors?

Tom..Hope to help..... :slight_smile:

On my first post I attached the wiring diagram and the first try at coding utilizing interrupts. Even show chips. Arduino nano 3.0. Powering with plug from wall to USB on Nano. Have plenty of power as lights on ULN2003 are nice and bright when stepper moving. I have even tried with additional power to ULN2003 along with USB connection to Nano. Have all grounds tied together.

datammwv:
On my first post I attached the wiring diagram and the first try at coding utilizing interrupts. Even show chips. Arduino nano 3.0. Powering with plug from wall to USB on Nano. Have plenty of power as lights on ULN2003 are nice and bright when stepper moving. I have even tried with additional power to ULN2003 along with USB connection to Nano. Have all grounds tied together.

Your schematic is ambiguous, poorly labelled, and incomplete.

What is the pin above the one marked D2?
What pin on the ULM2003 is pin 9 connected to?
Why did you leave out the switch? Show us where it's connected.
What is powering and/or activating your Remotec ZFM-80?

Hi, that diagram does not show your power supply, the motors, how you trigger the curtain with the remote removed, or any detail with reguard to earths.
Do you have bypassing and filtering capacitors?

Please a diagram, you must have one to get this far.

Tom..... :slight_smile:

I guess I do not understand why the diagram is missing some of what you say. I state Power supplied by usb. I show form pin 4 on Arduino Nano 3.0 ground connected to ground on ULN2003. I show at top I have a 22 ohm Resister. I do agree I didn't have the Stepper 28bjy-48 in the picture on the drawing along with not having the REmotec ZFM-80 connected in. That was because I removed the Remotec ZFM to prove out to myself that it was not causing the random movement.
When I add the Remotec into the picture I attach to + to the D2 Connection and the Ground to the ground connection as indicated by dashed lines in this new drawing.
Thank you,
Dave

Scan0004.pdf (162 KB)

Hi, are you using the computer USB port to power everything, the arduino, the stepper motor, the ZFM?
How much current is the project consuming when running the curtains?
Sorry but a proper circuit diagram shows all power connections, signal connections, stepper connections.
It is not good practice to put all this together and not draw a circuit as you do it.
You could have gnd connection problems, power supply problems.
Please a least a picture of the project.

Thanks Tom...... :slight_smile:

I have attempted to write it with finite state coding. I believe I still am missing something. Power is from a AC/DC adapter with 5 volts usb cable coming to Arduino Nano 3.0. (on previous post have scan004.pdf) The ground pin of the Nano 3.0 is connected to the ground pin of the ULN2003. There is plenty of power as motor turns very fast when told to do so. The lights on the ULN2003 are really bright. When I move the power wire from the ULN2003 to behind the 22ohm resister after pin 4 on the Arduino the lights on the ULN2003 go much dimmer and it does not have enough to drive the stepper. The Remotec ZFM is power by itself with 110 feed to it L/N. Then has two terminal for Relay Load

/**
 *  This sketch waits for the button to be pressed. The motor starts in forward direction, 
 *  then every time the button is pressed the motor moves in the other direction.
 */
#include <StepperMotor.h>

// 4 pins of the stepper motor board
#define _PIN1 11
#define _PIN2 10
#define _PIN3 9
#define _PIN4 8

// define states that will have
#define S_None     1 
#define S_Forward  2
#define S_Stop     3
#define S_Reverse  4

StepperMotor stepper(_PIN1, _PIN2, _PIN3, _PIN4);

void setup()
{
  pinMode(13,OUTPUT);
}

void loop()
{
  static int state = S_None; // initial state is 1, the "idle" state.
  switch(state)
  {
    case S_None:   
      //we just sit still here and doing nothing
      break;
    case S_Forward:
      stepper.move(8192);
      break;
    case S_Stop:
      stepper.stop();
      break;
    case S_Reverse:
      stepper.move(-8192);
      break;
  }}

Look at your code. Talk out loud as you read the code. What, exactly, does loop() do?

Right, it does absolutely nothing.

My First thought is it doesn't know how to proceed to the next step? I am not following how it knows to go to the next step as I did utilizing interrupts. "Look at pin 2" With finite state is will just go from step S_None to S_Forward to S_Stop to S_Reverse after a signal from pin 2? Or is it that as it "does" each states action it automatically goes to the next step/state?

I am not following how it knows to go to the next step as I did utilizing interrupts.

DO NOT EVEN CONSIDER INTERRUPTS AGAIN. Reading a switch, while the sketch is doing nothing else, is not going to result in missing switch presses.

You transition from some states to other states when the switch BECOMES pressed. You need to look at the state change detection example to see how that is done. You transition from some states to other states automatically, when what is being done in that state is done.

I'm sure that you can figure out which transitions require input and which are automatic.

Would this example be using int ?

or is it the correct way?

Constant which have in code
const int  buttonPin = 2;    // the pin that the pushbutton is attached to

Variables

int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

under void setup
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize the LED as an output:

Under void loop
// read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

// compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button
      // wend from off to on:
      buttonPushCounter++;

// save the current state as the last state, 
  //for next time through the loop
  lastButtonState = buttonState;

if (buttonPushCounter % 4 == 0)

Really, you can do this with two states: blinds_open and blind_closed. In each state you digitalRead the button. If it's high, run the stepper to put it in the other state. The stepping will take some time, likely enough to debounce your button, so there's no need to worry about detecting the change. No real need for the opening and closing states unless you want the button to be able to stop them.

Of course, you can then reduce this to just keeping a flag to tell you whether the blinds are open or closed and pick the step number based on that.