Making LED turn off

I'm am currently working on a project for which I am using 2 LEDs. LedPin1 works fine, but LedPin2 does not. The wiring is done properly because all components work, so it is just the coding where there is something wrong at the moment. this is what I am trying to do: Have LedPin2 always on, EXCEPT when I press button 2, then it should stay off for 10 seconds, until I tell it to turn on again. At the moment the LedPin2 only stays of for as long as I keep pressing down on the button, but as soon as I release it it turns on again.

This is my code:

#include <AccelStepper.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include <Servo.h> 

int modeChoice = 0;

const int buttonPin = 2;
const int buttonPin2 = 4;
const int ledPin = 12;  // RED LED
const int ledPin2 = 8;  // GREEN LED
int slide = A1;    // the slide is read through one analog pin, resitors provide different levels that point to which slide position is current
int rotation = A0; // the pin for the potentiometer

int buttonState = 0;
int buttonState2 = 0;

int buttonValRaw = 0; // a variable to store the raw analog reading of the buttons pin
int slideValRaw = 0;  // a variable to sore the raw analog reading of the slide pin
int valButton = 0;    // a variable to store the interpreted value, the exact pointer to a button
int valSlide = 0;     // a variable to store the interpreted value, the exact pointer to a slide position
int idleState = 0;    // a variable to toggle the servo idle behavior
int resetMotion = 0;  // a variable to return the arrayPosition to 0 if a button is pushed so that the behaviour starts at the beginning
int motionVar1;       // a variable to hold a motion position
int motionVar2;       // another variable to hold a motion position

int mySensorArray[20];  // an array with 20 slots to store raw potentiometer readings (for filtering)
int sensorArrayPos = 0; // the array position of interest.

const unsigned long period = 10000; // Stepper motor runs for 10 seconds
unsigned long timeButtonPressed; // for checking time at buttonpress
unsigned long currentMillis;

int servoMotionArray_B1[50] = {100,100,100,100,100,100,95,63,54,46,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45};
int servoMotionArray_B2[50] = {45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45};

//recorded motions for position implementation
int StepperMotionArray_B1[50] = {728,726,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728};  // close capsule
int StepperMotionArray_B2[50] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // open capsule

int arrayPosition = 0;

unsigned long mainTimer = 0; // a variable to time recording and playback
int timeBetweenSamples = 100; // the time between samples.

unsigned long debounceTimer = 0; // a variable to control a timer interval for debouncing of the buttons
int lastValButton = 0; // a variable to help debouncing of the buttons
int debounceFlag = 0; // another variabel to help debouncing of the buttons

// Setup motors
// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// Connect a stepper motor with 16 steps per revolution (2048 positions) to motor port #1 (M1 and M2) -- you need to change this if your stepper is on port #2
Adafruit_StepperMotor *myStepper = AFMS.getStepper(16, 1);
// And connect a DC motor to port M3 -- you need to change this if your DC is on a different port
Adafruit_DCMotor *myMotor = AFMS.getMotor(3);

Servo myservo1;   // servo object (employs the servo library that was included above)

// these are dedicated functions to make the steppermotor move
void forwardstep1() {
  myStepper->onestep(FORWARD, SINGLE);
}
void backwardstep1() {
  myStepper->onestep(BACKWARD, SINGLE);
}

//create aStepper object
AccelStepper aStepper(forwardstep1, backwardstep1); // use functions to step




// setup
void setup() {
  Serial.begin(9600); // start serial communication with 9600 baud rate

  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
  pinMode(buttonPin2, INPUT);
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  pinMode(ledPin2, OUTPUT);

  AFMS.begin();  // create with the default frequency 1.6KHz
  //AFMS.begin(1000);  // OR with a different frequency, say 1KHz

  myservo1.attach(9); // attach servo object to pin 9

  // turn on motor M3
  myMotor->setSpeed(0);
  myMotor->run(RELEASE);

  // setup the stepper
  aStepper.setSpeed(0); // this is used in the 'speed' implementation -> NOT used in this code

  aStepper.setMaxSpeed(200.0); // these are used in the 'position' implementation -> used in this code
  aStepper.setAcceleration(100.0);
  aStepper.moveTo(0);

  // synchronize the first timer cycle -- because the timer is starting at zero it generates negative values in the first 100 miliseconds after starting up when going through the timer cycle, creating potential erratic bahaviour-- giving it a delay at the end of the setup loop will eradicate this behaviour
  delay(1000);
}




void loop() {
 
  if (mainTimer < millis() - timeBetweenSamples) { // sampling only once per interval.
      mainTimer = millis();                          // time is rewritten to current millis starting a new interval.

  buttonState = digitalRead(buttonPin);
  buttonState2 = digitalRead(buttonPin2);
   
    if (buttonState == HIGH)  { // retrieve cup with servo motion 'cup' (hold button)
      if (idleState == 0) {                              // first idle state behaviour of servo
       motionVar1 = servoMotionArray_B1[arrayPosition];  // remove surface under cup holder
      }
      else if (idleState == 1){                          // second idle state behaviour of servo
        motionVar1 = servoMotionArray_B2[arrayPosition]; // let servo stay in position (cannot go back since cup is in the way)
      }
       myservo1.write(motionVar1);                       // Let Servo do the motion
       arrayPosition++;
     if (arrayPosition > 49) { // If one array/servo behaviour is finished it switches to the other
       arrayPosition = 0;
       idleState = 1;          // leave the servo in this position (not going back to other idle states anymore)
      }
    }

digitalWrite(ledPin2, HIGH);

    if (buttonState2 == HIGH) { // start process of output of coffee 'start'
       timeButtonPressed = millis();
       digitalWrite(ledPin2, LOW); // GREEN LED will reset again to perform 'start' action again  
       
// turn RED LED on
       digitalWrite(ledPin, HIGH); // let RED LED turn on

// first stepper behaviour
       motionVar2 = StepperMotionArray_B1[arrayPosition]; // capsule closes
        aStepper.moveTo(motionVar2);  // use moveTo to control position instead of speed for Stepper
        
      arrayPosition++;
      if (arrayPosition > 49) { // When recorded motions are finished...
        arrayPosition = 0;
        buttonState = 5;  // so it does not go back to servo/DC motions or stay in Stepper motions (LOW or HIGH)
      }
    }

// turn RED LED off
      currentMillis = millis();  // after period had passed RED LED turns off
       if (currentMillis - timeButtonPressed >= 10000){
         digitalWrite(ledPin, LOW);
     }

// turn GREEN LED on and open capsule after 5 sec after end of first stepper behaviour (10 sec after time button pressed)
      currentMillis = millis();                     
       if (currentMillis - timeButtonPressed >= 10000){ // 10 sec after button pressed
        digitalWrite(ledPin2, HIGH); // let GREEN LED turn on (red switches to green)
        motionVar2 = StepperMotionArray_B2[arrayPosition]; // capsule opens
         aStepper.moveTo(motionVar2);
    }
  }

  aStepper.run(); //stepper position implementation

}

If you want some action to continue for a period following a button press, you need to set a timer when the button press is detected, say :

uint32_t buttonPressedAtMs = millis() ;

then you keep testing, by say an if statement in the loop(), if the timer has expired, then act on it:

if ( millis() - buttonPressedAtMs <10000UL ) { do something } // 10 seconds

vkwochi:
then it should stay off for 10 seconds, until I tell it to turn on again

That's illogical.

You seem to be using the variable timeButtonPressed for the time for both LEDs - maybe you should have two separate variables?

This is not the right way to use millis() - it won't work if millis() rolls over

 if (mainTimer < millis() - timeBetweenSamples) {

it should be

 if (millis() - mainTimer >= timeBetweenSamples) {

You have the correct style elsewhere in your program

...R

PS ... if you use the AutoFormat tool your code will be indented consistently and much easier to read.

Breaking the code in loop() into several separate single purpose functions would also make it much easier to develop and maintain. See Planning and Implementing a Program

I have used the 'timebuttonpressed = millis()' in the code already, but because of the following code in the void loop() the LedPin2 turns back on as soon as I let go of the button:

digitalWrite(ledPin2, HIGH);

However, I don't know how to code this differently so it does not stay on when I want the button2 actions to happen until I tell it to come back on again.

        digitalWrite(ledPin2, HIGH);
        if (buttonState2 == HIGH) { // start process of output of coffee 'start'
            timeButtonPressed = millis();
            digitalWrite(ledPin2, LOW); // GREEN LED will reset again to perform 'start' action again

the above few lines don't make sense.

ledPin2 HIGH unconditionally. shouldn't you set LOW/HIGH either when a button is pressed or a timer expires?

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.