Go Down

Topic: Turn on outputs in a sequence while input is on. (Read 104 times) previous topic - next topic

rhaan

So I'm completely new to coding and I am struggling with a simple project. I have tried working this out myself  because I really want to understand what is going on in the project and the fact that i enjoy learning new things but I am under a bit of a time constraint.

It has to be really simple but I just wonder if I am making this more complicated than I need to.

I want the outputs to sequence through when the input turns on and only while the input is on (ie. output 1 turn on for 3 seconds then input 2 turn on a few milliseconds before output 1 turns off, output 2 will be on for 3 seconds then output 3 turn on a few milliseconds before output 2 turns off, output 3 will be on for 3 seconds and if the input is still on turn on output 1 a few milliseconds before output 3 turns off and cycle through again and again until the input is off.

I have attached a file of the project.

 Thanks in advance for the help and advice.

UKHeliBob

Please follow the advice on posting code in Read this before posting a programming question

In particular note the advice to Auto format code in the IDE and using code tags when posting code here
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

dougp

I don't trust atoms.  They make up everything.

No private consultations undertaken!

rhaan

Sorry, here is the code that I have so far. I have tried the several things at the same time code, I'm just having trouble understanding how to turn the outputs off as soon as the input button is released.



Code: [Select]
// --------CONSTANTS---------------

// the pin numbers for the LEDs
const int led_1_Pin = 4;
const int led_2_Pin = 7;
const int led_3_Pin = 8;

// the pin number for the button
const int inputSignal = 2;

// number of millisecs the Led's are off
const int led_1_OffDuration = 3000;
const int led_2_OffDuration = 3000;
const int led_3_OffDuration = 3000;

// number of millisecs that Led's are on
const int OnDuration_Led1 = 3000;
const int OnDuration_Led2 = 3000;
const int OnDuration_Led3 = 3000;



//------------ VARIABLES---------------------

// used to record whether the LEDs are on or off
byte led_1_State = LOW;           
byte led_2_State = LOW;
byte led_3_State = LOW;


unsigned long currentMillis = 0;   
unsigned long previousOnBoardLedMillis = 0;   // will store last time the LED was updated
unsigned long previousLed_1_Millis = 0;
unsigned long previousLed_2_Millis = 0;
unsigned long previousLed_3_Millis = 0;


//========================================

void setup() {

  Serial.begin(9600);
 
 
  // set the Led pins as output:
  pinMode(led_1_Pin, OUTPUT);
  pinMode(led_2_Pin, OUTPUT);
  pinMode(led_3_Pin, OUTPUT);
 
 
  // set the button pin as input with a pullup resistor to ensure it defaults to HIGH
  pinMode(inputSignal, INPUT);
 
 
 
}

//========================================

void loop() {

  currentMillis = millis();   
  int buttonState = digitalRead(inputSignal);


if (buttonState == HIGH) {
  if (led_1_State == LOW) {
    if (currentMillis - previousLed_1_Millis >= led_1_OffDuration) {
       led_1_State = HIGH;
       previousLed_1_Millis += led_1_OffDuration;
   
     Serial.print(previousLed_1_Millis);
    }
  }
    else {
      if (currentMillis - previousLed_1_Millis >= OnDuration_Led1) {
        led_1_State = LOW;
        previousLed_1_Millis += OnDuration_Led1;
       
        if (led_2_State == LOW) {
          if (currentMillis - previousLed_1_Millis >= led_2_OffDuration) {
            led_2_State = HIGH;
            previousLed_1_Millis += led_2_OffDuration;
          }
        }
        else {
          if (currentMillis - previousLed_1_Millis >= OnDuration_Led2) {
            led_2_State = LOW;
            previousLed_1_Millis += OnDuration_Led2;
       
            if (led_3_State == LOW) {
              if (currentMillis - previousLed_1_Millis >= led_3_OffDuration) {
                led_3_State = HIGH;
                previousLed_1_Millis += led_3_OffDuration;
              }
            }
            else {
              if (currentMillis - previousLed_1_Millis >= OnDuration_Led3) {
                led_3_State = LOW;
                previousLed_1_Millis += OnDuration_Led3;
              }
            }   
          }
        }   
      }
    }
 
  } 

  digitalWrite(led_1_Pin, led_1_State);
  digitalWrite(led_2_Pin, led_2_State);
  digitalWrite(led_3_Pin, led_3_State);
 
}

//========================================END

UKHeliBob

Quote
I'm just having trouble understanding how to turn the outputs off as soon as the input button is released.
If you use millis() for timing properly then the loop() function will repeat thousands of times per second.  On each iteration you can check the state of an input and compare it with the state last time it was checked.  If it has changed and is now in an off state then act as required
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

ToddL1962

#5
Sep 16, 2020, 09:21 pm Last Edit: Sep 16, 2020, 09:58 pm by ToddL1962
Your code is way too complicated for sequencing 3 LEDs on for 3 seconds a piece.  Here is one way to do it:

Code: [Select]

// --------CONSTANTS---------------

// the pin number for the button
const int inputSignal = 2;

// the pin numbers for the LEDs
const int ledPins[] = {4, 7, 8};

// number of millisecs that Led's are on
const int ledOnDuration[] = {3000, 3000, 3000};

const int numLeds = sizeof(ledPins)/sizeof(ledPins[0]);

//------------ VARIABLES---------------------

unsigned long previousMillis = 0;
int ledIndex = 0;

void setup()
{
  Serial.begin(9600);

  // set the Led pins as output:
  for (int i = 0; i < numLeds; i++) pinMode(ledPins[i], OUTPUT);

  // set the button pin as input with a pullup resistor to ensure it defaults to HIGH
  pinMode(inputSignal, INPUT);
}

void loop()
{
  int buttonState = digitalRead(inputSignal);
  static int prevButtonState = LOW;
  unsigned long currentMillis = millis();
 
  if (buttonState != prevButtonState)
  {
    if (buttonState == HIGH)
    {
      // Button has been pressed.  Begin sequence.
      ledIndex = 0;
      digitalWrite(ledPins[0], HIGH);
      previousMillis = currentMillis;
    }
    else
    {
      // Button has been release.  Turn all LEDs off.
      for (int i = 0; i < numLeds; i++) digitalWrite(ledPins[i], LOW);
    }
    prevButtonState = buttonState;
    delay(50); // debounce
  }
 
  if (buttonState == HIGH)
  {
    // Button is pressed check to see if current LED duration has expired
    if (currentMillis - previousMillis >= ledOnDuration[ledIndex])
    {
      // Turn current LED off
      digitalWrite(ledPins[ledIndex], LOW);
      ledIndex++;
      ledIndex %= numLeds;
      // Turn next LED on and reset the timer
      digitalWrite(ledPins[ledIndex], HIGH);
      previousMillis = currentMillis;
    }
  }
}

rhaan

That's what I figured.
I've tried using a separate function for each LED and I get the same result which is while I have the input button on the LED's stay on, the timers that I have set to turn the LED's off don't switch them off. The only way I can get the LED's to turn off is by releasing the input button.
I've tried putting the button state code in the main loop and also in each function loop.

Code: [Select]


void Led_1_State() {
  if (digitalRead(buttonPin) == HIGH)  {
     if (currentMillis - previousLed_1_Millis >= led_1_Interval) {
       led_1_State = HIGH;
       previousLed_1_Millis += led_1_Interval;
    }
  }
  else {
    if (currentMillis - previousLed_1_Millis >= blinkDuration) {
       led_1_State = LOW;
       previousLed_1_Millis += blinkDuration;
    }
  }   
}

ToddL1962

#7
Sep 16, 2020, 10:15 pm Last Edit: Sep 16, 2020, 10:16 pm by ToddL1962
That's what I figured.
I've tried using a separate function for each LED and I get the same result which is while I have the input button on the LED's stay on, the timers that I have set to turn the LED's off don't switch them off. The only way I can get the LED's to turn off is by releasing the input button.
I've tried putting the button state code in the main loop and also in each function loop.
One problem is you are evaluating the button's state and not looking for the state transition.  Look at the code I posted.  It starts the sequence when the button goes from LOW to HIGH and turns off all of the LEDs when the button goes from HIGH to LOW.  It continues executing the sequence as long as the button is HIGH.  Also, I used arrays which greatly shortened the length of the code.

I tested this code and it works.

rhaan

Thanks so much for the help. After studying the code i understand what it is doing.
I can program ladder logic all day long and enjoy it but I can see that coding is way different. I have a lot to learn.

Thanks again for the help.

ToddL1962

Thanks so much for the help. After studying the code i understand what it is doing.
I can program ladder logic all day long and enjoy it but I can see that coding is way different. I have a lot to learn.

Thanks again for the help.
No problem.  Glad it helped!

Go Up