Toggle (T) Flip Flop won't engage motor according to state

Hello,
Doing this code for a school project, and for it I am using a stepper motor. I have spent hours using multiple versions of the T Flip Flop, but no matter which one I use, the motor will only stay on for about a second or two before turning off. How can I make the motor stay on when toggled on?

#include <Stepper.h>
#define STEPS 100

Stepper stepper(STEPS, 8, 9, 10, 11);
bool enable = false;

void setup() {
  stepper.setSpeed(50);
  pinMode(7, INPUT);
  Serial.begin(9600);
}

void loop() {
  if (digitalRead(7) == HIGH) {
    delay(100);
    enable = !enable;
  }
  if (enable == true) {
    stepper.step(STEPS);
  }
}

enable is probably toggling, if you stab the button < 100 milliseconds.

Why not print out its value and see?

But your code makes no use of the current value enable.

You can name a variable however you want. In order for it to mean anything to the execution of your code, it must somehow enter into that code.

I'm thinking something like an if statement.

HTH

a7

OK, you changed the code in your top post. How is that now working for you?

a7

Literally just did some edits as well as value checking. I've fixed the error of it turning off, however now it stays on. According to the serial monitor, enable is immediately being set to 'true' after being toggled off.

Edit: I did remove the delay(100), however with or without the delay I still get the same problem.

Please in your next post show some stable code you think should work. And describe how it isn't working.

The delay is needed. This is just a crude manner of debouncing a switch, so.

a7

Here is a code that demonstrates how to write a function that creates a toogle-switch functionality with a momentary push-button.

This code is well organised in functions where each function does one thing

The code itself has additional explanations how it works

/* explanation of the most important details:

  realising a functionality where using a momentary push-button
  acts as a toogle-switch
  push       => activated  push again => DE-activated
  push again => activated  push again => DE-activated
  etc. etc. ...
  This needs quite some code. This code is well organised in MULTIPLE functions
  where each function is a senseful SUB-program

  This is the reason why function loop looks super-short:

  void loop () {
  activationMode = GetToggleSwitchState(); // must be executed all the time
  execute_if_Active(activationMode);       // function that does what its name says
  }

  Huh that's all? No. Of course there is more (below function loop)

  If you just want to APPLY the functionality to your own code
  replace the code inside function    void my_Action()
  with your own code that shall only be  executed if you activated execution
  with the momentary push-button

  I recommend to RENAME the function my_Action() to a SELF-explaining name
  This will cause a compiler-error which shows you where you have to rename
  the function-call of this function too (this is inside function execute_if_Active
  If you want to understand how it works read and analyse the rest of the functions.

*/

/*

overview:
function setup() is that function that is always executed only ONCE

the function loop() start doing what its nam says: LOOPING around and around infinetely
inside function 

loop() 
 - GetToggleSwitchState() 
 - execute_if_Active()
   - my_Action() 
   
loop() calls-->execute_if_Active() calls--->my_Action()

inside function myAction the onBoard-LED is made blinking

*/

#define ProjectName "Toggle Button demonstration"

// define IO-states for inputs with pull-up-resistors
// pull-up-resistors invert the logig
#define unPressed HIGH
#define pressed   LOW

const byte ToggleButtonPin = A0;

bool activationMode = false;
unsigned long myCounter = 0;
unsigned long MyBlinkTimer = 0;


void setup() {
  Serial.begin(115200); // adjust baudrate in the serial monitor to match the number
  Serial.println( F("Setup-Start") );
  printFileNameDateTime();

  pinMode (LED_BUILTIN, OUTPUT);  // used for indicating logging active or not
  digitalWrite(LED_BUILTIN, LOW);
  // wire button between IO-pin and GND
  // Pull-up-resistor inverts the logic
  // unpressed: IO-pin detects HIGH
  // pressed:   IO-Pin detects LOW
  pinMode(ToggleButtonPin, INPUT_PULLUP);
  MyBlinkTimer = millis();
}



// this is the function that is called
// inside function execute_if_Active()
void my_Action() {

  if ( TimePeriodIsOver(MyBlinkTimer, 250) ) {
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN) ); // read state of LED-output and set to invertetd state
  }
}


void loop () {
  activationMode = GetToggleSwitchState(); // must be executed all the time
  execute_if_Active(activationMode);       // function that does what its name says
}


bool GetToggleSwitchState() {
  // "static" makes variables persistant over function calls
  static bool toggleState     = false;
  static bool lastToggleState = false;

  static byte buttonStateOld = unPressed;
  static unsigned long buttonScanStarted  =  0;
  unsigned long buttonDebounceTime = 50;
  static unsigned long buttonDebounceTimer;

  byte buttonStateNew;

  if ( TimePeriodIsOver(buttonDebounceTimer, buttonDebounceTime) ) {
    // if more time than buttonDebounceTime has passed by
    // this means let pass by some time until
    // bouncing of the button is over
    buttonStateNew = digitalRead(ToggleButtonPin);

    if (buttonStateNew != buttonStateOld) {
      // if button-state has changed
      buttonStateOld = buttonStateNew;
      if (buttonStateNew == unPressed) {
        // if button is released
        toggleState = !toggleState; // toggle state-variable
      } // the attention-mark is the NOT operator
    }   // which simply inverts the boolean state
  }     // !true  = false   NOT true  is false
  //       !false = true    NOT false is true
  return toggleState;
}


void execute_if_Active(bool p_IsActivated) {
  printActionState(p_IsActivated);   // for demonstration purposes only

  if (p_IsActivated) {
    my_Action(); // <<<<== inside this function you do what shall be executed only if mode isActivated is true
  }
}



void printFileNameDateTime() {
  Serial.print( F("File   : ") );
  Serial.println( F(__FILE__) );
  Serial.print( F("Date   : ") );
  Serial.println( F(__DATE__) );
  Serial.print( F("Project: ") );
  Serial.println( F(ProjectName) );
}

// ignore at first
// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - startOfPeriod >= TimePeriod ) {
    // more time than TimePeriod has elapsed since last time if-condition was true
    startOfPeriod = currentMillis; // a new period starts right here so set new starttime
    return true;
  }
  else return false;            // actual TimePeriod is NOT yet over
}

void printActionState(boolean p_IsActivated) {
  static boolean lastIsActivated;
  
  if ( p_IsActivated != lastIsActivated) {
    // only if state of parameter p_logIsActivated has changed
    if (p_IsActivated) {
      Serial.println();
      Serial.println("start executing");
      Serial.println();
      digitalWrite(LED_BUILTIN, HIGH);
    }
    else { // not activated
      Serial.println();
      Serial.println("stopp executing");
      Serial.println();
      digitalWrite(LED_BUILTIN, LOW);
    }
    lastIsActivated = p_IsActivated; // update variable lastSDlogActive
  }  
}

best regards Stefan

@itsfoxy87 let's get your crude but simple program to function.

Here's your idea, only instead of starting and stopping a motor, we turn on and off an attached LED.

Note: I wired the switch in a conventional manner, between the input pin and ground, and used INPUT_PULLUP mode for it.

Therefore, the switch reads LOW when presst.

Note: I greatly increased the delay as I have fat fingers and have trouble getting on and off the buton fast enough.

bool enable = false;

void setup() {

//...
  pinMode(7, INPUT_PULLUP);
  pinMode(6, OUTPUT);

  Serial.begin(9600);
}

void loop() {
// wire your switch between the pin and ground. then when pressed it will read LOW

  if (digitalRead(7) == LOW) {
//...
    delay(300);
    enable = !enable;
  }

  Serial.println(enable);

  if (enable == true) {
    digitalWrite(6, HIGH);
  }
  else {
    digitalWrite(6, LOW);
  }
}

Once you have that working, please check the documentation on the Stepper so that you can confidently make the motor run where the code now lights the LED, and stop where the code now extinguishes the LED.

Once that functions to your satisifaction, you may want to ask about real switch handling to replace the "poor man's" method which though effective is crude and will not serve you very well in anything larger than this small sketch.

a7

The switch I'm using is weird, it's a limit switch module from Adeept, it only functions if it is powered by both VCC and Ground, which the input then goes into 7. I don't have any LEDs or really any other Arduino component at the moment, I'll have to get one from home tomorrow before school.

Edit: The Arduino is unplugged in this photo, hence the light being off.

You have one led at hand:

the onboard LED of the arduino-board itself.
usually the onboard-LED is wired to IO-pin 13

For the demo-code I have posted you would simply add

stepper.step(1); // do a SINGLE step

inside the function myAction

What do you think:
Will you be able to copy and paste the code-version below into the arduino-IDE
compile and flash the code for a test?

The code below uses IO-pin 7 as start/stop button and uses the stepper-library to drive your stepper-motor.

The button on IO-pin 7 must be connected to IO-pin and ground.
It uses the input-mode INPUT_PULLUP which is different from your mode "INPUT"

#include <Stepper.h>
#define STEPS 100

Stepper stepper(STEPS, 8, 9, 10, 11);

#define ProjectName "Toggle Button stepper on/off"

// define IO-states for inputs with pull-up-resistors
// pull-up-resistors invert the logig
#define unPressed HIGH
#define pressed   LOW

const byte ToggleButtonPin = 7;

bool activationMode = false;
unsigned long myCounter = 0;
unsigned long MyBlinkTimer = 0;


void setup() {
  Serial.begin(115200); // adjust baudrate in the serial monitor to match the number
  Serial.println( F("Setup-Start") );
  printFileNameDateTime();

  pinMode (LED_BUILTIN, OUTPUT);  // used for indicating logging active or not
  digitalWrite(LED_BUILTIN, LOW);
  // wire button between IO-pin and GND
  // Pull-up-resistor inverts the logic
  // unpressed: IO-pin detects HIGH
  // pressed:   IO-Pin detects LOW
  pinMode(ToggleButtonPin, INPUT_PULLUP);
  MyBlinkTimer = millis();
}



// this is the function that is called
// inside function execute_if_Active()
void my_Action() {
  stepper.step(1); // do a SINGLE step
  
  if ( TimePeriodIsOver(MyBlinkTimer, 250) ) {
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN) ); // read state of LED-output and set to invertetd state
  }
}


void loop () {
  activationMode = GetToggleSwitchState(); // must be executed all the time
  execute_if_Active(activationMode);       // function that does what its name says
}


bool GetToggleSwitchState() {
  // "static" makes variables persistant over function calls
  static bool toggleState     = false;
  static bool lastToggleState = false;

  static byte buttonStateOld = unPressed;
  static unsigned long buttonScanStarted  =  0;
  unsigned long buttonDebounceTime = 50;
  static unsigned long buttonDebounceTimer;

  byte buttonStateNew;

  if ( TimePeriodIsOver(buttonDebounceTimer, buttonDebounceTime) ) {
    // if more time than buttonDebounceTime has passed by
    // this means let pass by some time until
    // bouncing of the button is over
    buttonStateNew = digitalRead(ToggleButtonPin);

    if (buttonStateNew != buttonStateOld) {
      // if button-state has changed
      buttonStateOld = buttonStateNew;
      if (buttonStateNew == unPressed) {
        // if button is released
        toggleState = !toggleState; // toggle state-variable
      } // the attention-mark is the NOT operator
    }   // which simply inverts the boolean state
  }     // !true  = false   NOT true  is false
  //       !false = true    NOT false is true
  return toggleState;
}


void execute_if_Active(bool p_IsActivated) {
  printActionState(p_IsActivated);   // for demonstration purposes only

  if (p_IsActivated) {
    my_Action(); // <<<<== inside this function you do what shall be executed only if mode isActivated is true
  }
}



void printFileNameDateTime() {
  Serial.print( F("File   : ") );
  Serial.println( F(__FILE__) );
  Serial.print( F("Date   : ") );
  Serial.println( F(__DATE__) );
  Serial.print( F("Project: ") );
  Serial.println( F(ProjectName) );
}

// ignore at first
// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - startOfPeriod >= TimePeriod ) {
    // more time than TimePeriod has elapsed since last time if-condition was true
    startOfPeriod = currentMillis; // a new period starts right here so set new starttime
    return true;
  }
  else return false;            // actual TimePeriod is NOT yet over
}

void printActionState(boolean p_IsActivated) {
  static boolean lastIsActivated;
  
  if ( p_IsActivated != lastIsActivated) {
    // only if state of parameter p_logIsActivated has changed
    if (p_IsActivated) {
      Serial.println();
      Serial.println("start executing");
      Serial.println();
      digitalWrite(LED_BUILTIN, HIGH);
    }
    else { // not activated
      Serial.println();
      Serial.println("stopp executing");
      Serial.println();
      digitalWrite(LED_BUILTIN, LOW);
    }
    lastIsActivated = p_IsActivated; // update variable lastSDlogActive
  }  
}

best regards Stefan

Then start even simpler.

If you are not comfortable with using a jumper or even a short length of plain wire between the I/O pin and ground, see if you can get a LED to simply echo the condition coming from your weird switch.

void loop() {
  int theSwitch = digitalRead(7);
  if (digitalWrite(6, theSwitch);
}

Then if you cannot change the sense of the switch as I did, just change the logic of the if statement in your poor man's switch handler, viz:

You can use the build-in LED on your Arduino board. On the UNO this is at digital output 13. Usually it is also on a named pin LED_BUILTIN, like

// in setup()

  pinMode(LED_BUILTIN, OUTPUT);

// and then anywhere

  digitalWrite(LED_BUILTIN, HIGH);

which I hope is obvious by now.

There also appear to be LEDs on the weird switch board. I saw similar modules but did not find your exact version, so cannot advise with actual code.

Do you have a part number or link to where it was purchased, or a pointer to a product of whichit is a part?

It will be good for you to develop an inquisitive nature and a willingness to experiment. It is also a good idea to break even such a simple sketch as you are working on into the tiniest of pieces.

You could also do a huge amount of the work by using a simulator. Try

the best of them at the moment. I'd like to say it is mostly intuitive, dare to pretend that you know what you are doing and see if you can rig a pushbutton and LED to perform the code in my #7 above.

The simulator will let you add a stepper motor to this sketch. I am usually able to do nearly 100 percent of the software for a small project without needing to touch any hardware except my keyboard and mouse.

It makes taking a sketch into the real world, where there will inevitably be issues cropping of of a different nature much easier. If you know the software works, and you have problems, it is very more likely to be hardware which cuts way back on the areas where you must focus.

a7